Hibernate - 使用包含父ID的复合键 - OneToMany

时间:2016-12-27 17:34:21

标签: java hibernate foreign-key-relationship hibernate-onetomany

(原始问题已更改,请参阅以下更新。)

我无法让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。我试过了,但到目前为止没有成功。

1 个答案:

答案 0 :(得分:1)

它可能取决于您的预期语义,但如果子PK也是Parent的FK,那么我认为它代表IS-A类型关系 - 或者,在数据库术语中,CHILD是一个扩展表父母。您可以将其设置为每类表继承。

<强>更新

因此根据您的更新,Child中的ParentID不是Child的PK;这意味着它不应该用@Id注释,并且应该像任何其他FK一样进行设置。我会考虑不映射ParentID,而是映射Parent,尽管是YMMV。

然后一个单独的问题是,什么(如果有的话 - 尽管如果没有,你可能会遇到麻烦)是孩子的唯一ID?它是一个独立指定的代理人吗?包含父ID的复合?或者是其他东西?所有这些案例都可以适应,但如果没有更多关于你需要它的信息,我可能无法详细说明每种可能性......