0

我有两个实体父母和孩子。父母只能有一个孩子,因此它包含一个孩子的外键。

所有 ID 均由 IdentifierGenerator 的自定义实现生成。对于某些实体,我想手动设置 ID。所以我在我的自定义 IdentifierGenerator 中找到了一种方法来获取 id 字段的值。

问题是,当子项的 id 先前已定义且子项尚未持久化时,永远不会调用生成器。

父 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>

子 hbm.xml 文件:

<id name="id" type="java.lang.Long" unsaved-value="null">
    <column name="ID" sql-type="BIGINT"/>
    <generator class="com.EntityIdGenerator">
    </generator>
</id>

我怎样才能改变这种行为?

任何想法 ?

提前致谢。

4

2 回答 2

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();

希望这可以帮助。

莎拉

于 2013-09-07T04:13:52.097 回答
0

您是否尝试过将其配置为手动 id,然后使用拦截器或事件侦听器来为未手动分配的情况生成值,而不是使用生成器?

莎拉

于 2013-09-06T02:28:41.473 回答