JPA - Cascade坚持一对一的关系

时间:2015-09-24 10:50:23

标签: java jpa primary-key cascade one-to-one

我有一对一的双向关系,我希望其中一个实体的ID也是另一个实体的ID。

我的代码是这样的:

@Entity
public class UserProfile extends AbstractEntity{
     @OneToOne(mappedBy="user",cascade = CascadeType.ALL)
     private UserPreferences preferences;

     //...
}

另一个实体:

@Entity
public class UserPreferences implements Serializable{
  @Id
  @Column(name="USER_ID")
  private String userId;  // I want USER_ID act as both primary key and foreign key

  @OneToOne
  @PrimaryKeyJoinColumn(name="USER_ID")
  UserProfile user;

  // ...
}

但是当我坚持这样的UserProfile时:

UserPreferences pref = new UserPereferences();
pref.setUser(user);
user.setPreferences(pref);
em.persist(user);

它给了我一个错误,上面写着UserPreferences' Id不能为空 似乎jpa不明白它应该使用UserProfile Id作为UserPreferences Id。

错误:

Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Column 'USER_ID' cannot be null
Error Code: 1048
Call: INSERT INTO USERPREFERENCES (USER_ID) VALUES (?)

我的代码中有什么问题吗? jpa可以解决这个问题吗?或者我应该分开坚持下去?

提前致谢

3 个答案:

答案 0 :(得分:1)

使用@MapsId代替@PrimaryKeyJoinColumn

@Entity
public class UserPreferences implements Serializable{
  @Id
  @Column(name="USER_ID")
  private String userId;  // I want USER_ID act as both primary key and foreign key

  @MapsId
  @OneToOne
  //@PrimaryKeyJoinColumn(name="USER_ID")
  UserProfile user;

  // ...
}

这将在DDL生成期间创建外键定义。

CREATE TABLE USERPREFERENCE (USER_ID VARCHAR(255) NOT NULL, PRIMARY KEY (USER_ID))
CREATE TABLE USERPROFILE (ID VARCHAR(255) NOT NULL, PRIMARY KEY (ID))
ALTER TABLE SESSION ADD CONSTRAINT FK_SESSION_USER_ID FOREIGN KEY (USER_ID) REFERENCES USER (ID)
ALTER TABLE USERPREFERENCE ADD CONSTRAINT FK_USERPREFERENCE_USER_ID FOREIGN KEY (USER_ID) REFERENCES USERPROFILE (ID)

答案 1 :(得分:1)

你不这样做

@Id
@Column(name="USER_ID")
private String userId;  // I want USER_ID act as both primary key and foreign key

@OneToOne
@PrimaryKeyJoinColumn(name="USER_ID")
UserProfile user;

因为您使用了两次引用,所以只需要使用一个

@OneToOne
@Id
@Column(name="USER_ID")
UserProfile user;

像这样的例子

答案 2 :(得分:1)

注释本身不足以实际上对相关表进行级联操作。您还应该在FK UserPreferences上找到“ON XXX CASCADE” - >用户配置。

如果您使用JPA创建DDL,则应在UserPreferences表上阅读。如果已经创建了DB,则应删除约束,然后手动添加CASCADE,如下所示:

 alter table UserPreferences  drop constraint OldConstraintName;
 alter table UserPreferences  add constraint FK_ABABA foreign key (USERID) references UserProfile(USERID) on delete/update/etc.. cascade