我有两个实体Parent和Child。父母只能有一个孩子,因此它包含孩子的外键。
所有ID都由IdentifierGenerator的自定义实现生成。对于某些实体,我想手动设置ID。所以我在自定义IdentifierGenerator中找到了一种方法来获取id字段的值。
问题是,当孩子的id先前被定义并且孩子还没有被持久化时,永远不会调用生成器。
parent-hbm.xml文件:
<hibernate-mapping default-cascade="all">
<class name="com.ParentImpl" table="Parent" dynamic-insert="false" dynamic-update="false">
<cache usage="read-write" />
<id name="id" type="java.lang.Long" unsaved-value="null">
<column name="ID" sql-type="BIGINT"/>
<generator class="com.EntityIdGenerator">
</generator>
</id>
<many-to-one name="child" class="com.ChildImpl" foreign-key="CHILDSC" cascade="all" lazy="false" fetch="select">
<column name="CHILD_FK" not-null="true" sql-type="BIGINT" unique="true"/>
</many-to-one>
</class>
</hibernate-mapping>
child-hbm.xml文件:
<id name="id" type="java.lang.Long" unsaved-value="null">
<column name="ID" sql-type="BIGINT"/>
<generator class="com.EntityIdGenerator">
</generator>
</id>
如何更改此行为?
有什么想法吗?
提前谢谢。
答案 0 :(得分:0)
您是否尝试将其配置为手动ID,然后使用拦截器或事件侦听器,而不是使用生成器,而是在未手动分配的情况下为这些情况生成值?
萨拉
答案 1 :(得分:0)
如果ID尚未拥有,您可以使用@PrePersist注释生成ID。我对你的评论感到惊讶,因为它无法通过拦截器或事件监听器完成,所以我决定尝试一下。
以下是如何操作的示例。我有一个类“Test”,它有一个手动分配的id,然后我实现了一个@PrePersist方法,如果它还没有ID,则将ID分配给hashCode()值。您可以替换所需的任何生成方案来代替hashCode()调用。
@Entity
@Table (name="Test")
public class Test{
@Id
@Column(name="id")
private String id;
@Column(name="PROPERTY")
private String property;
public Test() {
}
... // Other constructors, getters and setters
@PrePersist
void generateId() {
if (id == null) {
id = Integer.toHexString(hashCode());
}
}
我测试了已分配和未分配的ID,同时创建了新实体并更新了现有实体,并没有遇到任何问题。
创建新实体的示例:
Test assigned = new Test("assigned", "p1");
Test generate = new Test();
generate.setProperty("p2");
manager.persist(assigned);
manager.persist(generate);
manager.getTransaction().commit();
更新现有实体的示例:
Test update = manager.find(Test.class, "assigned");
actionUpdate.setProperty("imageUpdated");
Test update2 = manager.find(Test.class, "some-generated-id");
update2.setProperty("videoUpdated");
manager.getTransaction().commit();
希望这有帮助。
萨拉