我想创建两个表USER和USERDETAIL来实现:
USERDETAIL引用了USER表。
USER表上的操作不需要知道USERDEAIL表是否存在。
这应该是一对一的非双向关系。
实体类:
@Entity
@Table(name="USER")
public class User implements Serializable{
@Id
@Column(name="ID")
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
private String id;
//...
}
@Entity
@Table(name="USERDETAIL")
public class UserDetail implements Serializable{
@Id
@Column(name="ID")
@GeneratedValue(generator = "gen")
@GenericGenerator(name = "gen", strategy = "foreign",
parameters = @Parameter(name = "property", value = "user"))
private String id;
@OneToOne(optional= false , targetEntity=User.class, cascade= CascadeType.ALL)
@OnDelete(action = OnDeleteAction.CASCADE)
//@JoinColumn(name="foreign_id",referencedColumnName="ID")
@PrimaryKeyJoinColumn
private User user;
//...
}
这正确地创建了两个表,并且USERDETAIL具有外键约束,其主键是由USER的id引用的。但是,“删除”操作为Restrict
,但不是Cascade
。因此,我无法删除一行USER。
我正在使用MySQL Sever 5.1。它似乎不支持删除操作是级联。因为我可以手动删除约束并添加一个设置为on的新约束是cascade并按预期工作。
答案 0 :(得分:0)
您的代码应为:
@Entity
@Table(name="USER")
public class User implements Serializable{
@Id
@Column(name="ID")
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
private String id;
//...
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="userdetail_id")
public UserDetail getUserDetail() {
...
}
}
@Entity
@Table(name="USERDETAIL")
public class UserDetail implements Serializable{
@Id
@Column(name="ID")
@GeneratedValue(generator = "gen")
@GenericGenerator(name = "gen", strategy = "foreign",
parameters = @Parameter(name = "property", value = "user"))
private String id;
@OneToOne(optional= false , targetEntity=User.class, mappedBy = "userDetail")
@PrimaryKeyJoinColumn
private User user;
//...
}
基本上,我建议双向使用,User类是所有者(通过在UserDetail类中使用mappedBy)。这样,当您删除用户时,将删除用户详细信息。
答案 1 :(得分:0)
最后,我已经解决了这个问题。
首先,我遵循http://www.mkyong.com/hibernate/hibernate-one-to-one-relationship-example-annotation/来创建oneToOne映射实体。
但是,当我启动Tomcat时,它总是在映射上抛出NullPointerException
。因此,我想出了我的问题实体,除了删除之外似乎工作得很好。
我终于意识到这只是一个hibernate-anoatation导致的错误。然后我使用3.4.0.ga版本并再次关注该链接。通过替换@GeneratedValue(strategy = IDENTITY)
(我不知道为什么使用它,hibernate无法创建表)
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
它像我预期的那样工作。
虽然表上没有外键约束,但删除所有者(USER)表确实也可以使用hibernate句柄正确删除子(USERDETAIL)表。
我也不需要担心没有子字段的更新所有者表。 Khue Vu说,mappedBy
方实际上没有定义物理映射。 Hibernate非常聪明,不会删除关系。