【发布时间】:2016-12-27 17:34:20
【问题描述】:
(原问题已更改,请参阅下面的更新。)
我无法让 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。我试过了,但到目前为止没有成功。
【问题讨论】:
-
您应该在关系的另一端声明 JoinColumn。在
Child类中声明@ManyToOne关系。但是IMO,你有一个设计问题:如果Parent有多个Child,Parent怎么可能是Child的主键? (多个Child将具有相同的Parent,因此具有相同的主键)。 -
哦,你是对的。这不是真正的主键!!!只是一把钥匙!!该表没有真实 ID。
标签: java hibernate foreign-key-relationship hibernate-onetomany