(原始问题已更改,请参阅以下更新。)
我无法让hibernate设置子对象的主键。主键与父键的主键相同。
这就是父母的样子:
@Entity
@Table(name = "PARENT")
@SequenceGenerator(name = "SEQ", allocationSize = 1, sequenceName = "seq_parent_id")
public class Parent {
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ")
private Long id;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@Fetch(value = FetchMode.SUBSELECT)
@JoinColumn(name = "PARENT_ID")
private Set<Child> children;
这就是孩子的样子:
@Entity
@Table(name = "CHILDREN")
public class Child {
@Id
@Column(name = "PARENT_ID")
private Long parentId;
现在,当我运行JUnit存储库测试时,我试图用子实体保存父实体,我得到了异常:
org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): ...
让hibernate自动将Child.parentId设置为parent.id的正确方法是什么?
我试过给孩子一个父母。但遇到其他例外,因为Parent不是Id。
更新
我意识到儿童的Id不是真正的主键。它只是一个映射键。 parent.id可以有几个子条目。
更新
现在我开始意识到我真正需要的东西:
子主键是三个值中的复合键:父ID和另外两个String值。
@Entity
@Table(name = "CHILDREN")
public class Child {
@Column(name = "PARENT_ID")
private Long parentId;
@Column(name = "PROPERTY_NAME")
private String propertyName;
@Column(name = "ANOTHER_PROPERTY")
private String anotherProperty;
@Column(name = "PROPERTY_VALUE")
private String propertyValue;
所以我需要使用parentId,properyName和anotherProperty映射复合键。 propertyValue是该条目的实际值。
我想我可能需要使用IdClass或embeddedId。我试过了,但到目前为止没有成功。
答案 0 :(得分:1)
它可能取决于您的预期语义,但如果子PK也是Parent的FK,那么我认为它代表IS-A类型关系 - 或者,在数据库术语中,CHILD是一个扩展表父母。您可以将其设置为每类表继承。
<强>更新强>
因此根据您的更新,Child中的ParentID不是Child的PK;这意味着它不应该用@Id
注释,并且应该像任何其他FK一样进行设置。我会考虑不映射ParentID,而是映射Parent,尽管是YMMV。
然后一个单独的问题是,什么(如果有的话 - 尽管如果没有,你可能会遇到麻烦)是孩子的唯一ID?它是一个独立指定的代理人吗?包含父ID的复合?或者是其他东西?所有这些案例都可以适应,但如果没有更多关于你需要它的信息,我可能无法详细说明每种可能性......