当尝试保存具有复合主键的实体时出现了 SQLSyntaxErrorException。

huangapple go评论156阅读模式
英文:

SQLSyntaxErrorException when trying to save Entity with Composite Key

问题

以下是翻译好的内容:

这些是我的类:

UserActivity

  1. @Entity
  2. @Data
  3. @IdClass(UserActivityId.class)
  4. public class UserActivity {
  5. @ManyToOne
  6. private User user;
  7. @Id
  8. @Column(name = "user_id", insertable = false, updatable = false)
  9. private Long userId;
  10. @ManyToOne
  11. private Stream stream;
  12. @Id
  13. @Column(name = "stream_id", insertable = false, updatable = false)
  14. private Long streamId;
  15. @Id
  16. private String userIp;
  17. //...还有8个字段
  18. }

UserActivityId

  1. @Data
  2. public class UserActivityId implements Serializable {
  3. private Long userId;
  4. private Long streamId;
  5. private String userIp;
  6. //构造函数
  7. }

Stream

  1. @Entity
  2. @Data
  3. public class Stream {
  4. @Id
  5. @GeneratedValue(strategy = GenerationType.IDENTITY)
  6. private Long id;
  7. @OneToMany(mappedBy = "stream")
  8. private List<UserActivity> UserActivities = new ArrayList<>();
  9. }

User

  1. public class User {
  2. @Id
  3. @GeneratedValue(strategy = GenerationType.SEQUENCE)
  4. protected long id;
  5. }

UserActivityRepository

  1. public interface UserActivityRepository extends JpaRepository<UserActivity, UserActivityId> {
  2. }

但是当我尝试像这样保存一个实体:

  1. var stream = streamRepository.findById(activity.getStreamId);
  2. var user = userRespository.findById(activity.getUserId);
  3. activity.setStream(stream);
  4. activity.setUser(user);
  5. userActivityRepository.save(activity);

我会得到一个异常,类似于这样的:

  1. java.sql.SQLSyntaxErrorException: (conn=1058) Could not set parameter at position 12 (values was 1)
  2. Query - conn:1058(M) - "insert into user_activity (a, b, c, d, e, f, g, h, user_id, stream_id, user_ip) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"

这很奇怪,因为我只有11个字段,但 Hibernate 却试图设置第12个参数。我尝试重新创建数据库,问题仍然存在,但是当我移除复合键时,它可以正常工作。

英文:

these are my classes

UserActivity

  1. @Entity
  2. @Data
  3. @IdClass(UserActivityId.class)
  4. public class UserActivity {
  5. @ManyToOne
  6. private User user;
  7. @Id
  8. @Column(name = &quot;user_id&quot;, insertable = false, updatable = false)
  9. private Long userId;
  10. @ManyToOne
  11. private Stream stream;
  12. @Id
  13. @Column(name = &quot;stream_id&quot;, insertable = false, updatable = false)
  14. private Long streamId;
  15. @Id
  16. private String userIp;
  17. //...8 more fields
  18. }

UserActivityId

  1. @Data
  2. public class UserActivityId implements Serializable {
  3. private Long userId;
  4. private Long streamId;
  5. private String userIp;
  6. //constructors
  7. }

Stream

  1. @Entity
  2. @Data
  3. public class Stream {
  4. @Id
  5. @GeneratedValue(strategy = GenerationType.IDENTITY)
  6. private Long id;
  7. @OneToMany(mappedBy = &quot;stream&quot;)
  8. private List&lt;UserActivity&gt; UserActivities = new ArrayList&lt;&gt;();
  9. }

User

  1. public class User {
  2. @Id
  3. @GeneratedValue(strategy = GenerationType.SEQUENCE)
  4. protected long id;
  5. }

UserActivityRepository

  1. public interface UserActivityRepository extends JpaRepository&lt;UserActivity, UserActivityId&gt;
  2. }

but when i try to save an entity like this :

  1. var stream = streamRepository.findById(activity.getStreamId);
  2. var user = userRespository.findById(activity.getUserId);
  3. activity.setStream(stream);
  4. activity.setUser(user);
  5. userActivityRepository.save(activity);

i get and exception like this:

  1. java.sql.SQLSyntaxErrorException: (conn=1058) Could not set parameter at position 12 (values was 1)
  2. Query - conn:1058(M) - &quot;insert into user_activity (a, b, c, d, e, f, g, h, user_id, stream_id, user_ip) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)&quot;

which is strange because i only have 11 fields and hibernate is trying to set the 12th parameter
i tried recreating the database and the problem persisted, but when i remove the composite key it works

答案1

得分: 0

insertable=false, updatable=false 的定义在需要通过 OneToOneManyToOne 映射在实体中多次映射字段时非常有用。

我认为要解决这个问题,你需要从 Column 注解中移除 insertable=false, updatable=false

参考链接:
http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Primary_Keys_through_OneToOne_Relationships

英文:

Defining insertable=false, updatable=false is useful when you need to map a field more than once in an entity through a OneToOne or ManyToOne mapping.

I think to fix this issue you need to remove insertable=false, updatable=false from the Column annotation.

See,
http://en.wikibooks.org/wiki/Java_Persistence/Identity_and_Sequencing#Primary_Keys_through_OneToOne_Relationships

答案2

得分: 0

因此,我最终找到了问题所在,我需要将@id放在关系引用(Stream、User)之上,而不是它们的外键上,另外我还需要为它们添加@MapsId

  1. @ManyToOne
  2. @Id
  3. @MapsId
  4. private User user;
  5. @Column(name = "user_id", insertable = false, updatable = false)
  6. private Long userId;
  7. @ManyToOne
  8. @Id
  9. @MapsId
  10. private Stream stream;
  11. @Column(name = "stream_id", insertable = false, updatable = false)
  12. private Long streamId;
  13. @Id
  14. private String userIp;
英文:

So i finally out found what the problem was,i had to place @id above the relationship references (Stream, User) instead of their foreign keys, also i needed to add @MapsId to them

  1. @ManyToOne
  2. @Id
  3. @MapsId
  4. private User user;
  5. @Column(name = &quot;user_id&quot;, insertable = false, updatable = false)
  6. private Long userId;
  7. @ManyToOne
  8. @Id
  9. @MapsId
  10. private Stream stream;
  11. @Column(name = &quot;stream_id&quot;, insertable = false, updatable = false)
  12. private Long streamId;
  13. @Id
  14. private String userIp;

huangapple
  • 本文由 发表于 2020年8月24日 22:33:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/63563132.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定