【问题标题】:generate id for self referencing table hibernate mapping为自引用表休眠映射生成 id
【发布时间】:2011-08-19 20:30:19
【问题描述】:

您好,我在 DB2 数据库上有一个如下表:

id (PKey) doc_id(FKey 指向 id) 不为空

这是一个我无法更改的奇怪旧表。我也无法编写/修改触发器。

我正在尝试为此表创建一个休眠映射,但我不知道如何编写这种奇怪的关系。

我有两个选择: 1- 告诉 Hibernate 将 id 和 doc_id 保留为 null 然后触发器将为我设置值。

2- 想办法告诉 hibernate 使用序列同时设置两个值的值。

我似乎无法找到让 hibernate 执行此操作的方法?

非常感谢任何帮助。

<id name="id" type="java.lang.Long" column="ID">
        <generator class="sequence">
            <param name="sequence">SQ_DCMNT</param>
        </generator>
</id>

<property name="packageDcmntId" generated="insert">
        <column name="PACKAGE_DCMNT_ID" not-null="true"/>
</property>

【问题讨论】:

    标签: hibernate db2


    【解决方案1】:

    我会将此实体配置为使用SequenceGeneratorSequenceHiLoGenerator 的自定义子类来生成其ID。这个自定义子类会像这样覆盖 generate 方法:

    @Override
    public Serializable generate(final SessionImplementor session, Object obj) {
        Serializable result = super.generate(session, obj);
        ((MyBizarreEntity) obj).setPackageDcmntId((Long) result);
        return result;
    }
    

    这样,实体的属性将在插入之前自动具有生成的 ID 的值,这是必要的,因为该列具有非空约束。

    我没有测试过,但应该可以。

    或者您可以只为 ID 使用常规序列生成器,确保访问类型是 property 而不是 field,然后实现 setId 方法,例如这个:

    /**
     * Sets the ID as well as the packageDcmntId, since they share the same value
     */
    public void setId(Long id) {
        this.id = id;
        this.packageDcmntId = id;
    }
    

    【讨论】:

    • 感谢您的解决方案,但这有点像 hack 并将生成器绑定到不理想的实体。
    • 拥有如此糟糕的数据库设计并不理想,我怀疑您会找到一个干净的解决方案而不是针对此类事情的破解。您可以通过使其使用反射来访问属性等来使生成器更具可配置性,但我希望您的架构中不会有多个这样的表。如果我是对的,那么请保持简单,然后对实体进行硬编码。如果你改变它,它甚至会在编译时被检测到。另一种方案是自己调用序列,手动生成分配ID,同时让setId改变其他字段值。
    • 补充说明:如果访问类型是属性,序列生成器应该调用setId方法。如果这个方法也改变了其他字段,问题就解决了。不需要自定义生成器。
    • hbm 文件中的 怎么样?我可以用它来插入对象吗?
    • 您能否详细说明您的最后评论?
    猜你喜欢
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 2019-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多