【问题标题】:Hibernate: How to model an Inheritance type structure and do operations without explicit castingHibernate:如何建模继承类型结构并在没有显式转换的情况下进行操作
【发布时间】:2017-09-20 10:49:13
【问题描述】:

我有一个应用程序,它使用传入的消息,解析消息中存在的数据,然后将规则应用于该数据。在 Rule 实体上,有一列用于区分规则的type

我想将规则的结果持久化到分隔表或子类,具体取决于规则的类型 strong> 处理它们。

我目前正在通过创建父 @MappedSuperclass(抽象)BaseResult 对象以及 AppleResultOrangeResult @Enitiy 来解决这个问题扩展了 BaseResult

我的问题是,鉴于下面的陈述,我如何改进/注释模型中的对象,以便在访问/持久化时不必为每个实例进行 instanceof 检查?现在这是我必须做的,以避免“baseresult 不存在”SQL 语法异常:

public void save(BaseResult baseResult) {
    if (baseResult instanceof AppleResult) {
        jpaApi.em().merge((AppleResult) baseResult);
    } else if (baseResult instanceof OrangeResult) {
        jpaApi.em().merge((OrangeResult) baseResult);
    }
}

我希望有一个比必须执行 if/else 并根据结果显式转换更优雅的解决方案。我正在考虑使用诸如 @DiscriminatorValue 注释之类的东西来使用泛型,但这些似乎都要求在我的情况下 BaseResult 也是一个实体,但事实并非如此。

【问题讨论】:

    标签: java hibernate jpa data-modeling multi-table-inheritance


    【解决方案1】:

    您应该使用@Inheritance。那么,保存就很简单了:

    public void save(final BaseResult baseResult) {
        jpaApi.em().merge(baseResult);
    }
    

    使用哪种继承策略取决于您当前的数据库设计,但我猜您对每个子类都有一个表,所以是这样的:

    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public abstract class BaseResult {
        //...
    }
    
    @Entity
    public class AppleResult extends BaseResult {
        //...
    } 
    

    在超类上使用@Entity 不是问题,因为无论如何它都是abstract..

    另外,使用merge 通常是不应该做的事情,你应该只在事务中操作你的实体,并在事务提交时自动保存在数据库中:

    @Transactional //either this...
    public void doStuff(final ResultCommand command) {
        //begin transaction <-- ...or this
        final BaseResult result = em.find(BaseResult.class, command.getResultId());
        result.apply(command);
        //end transaction
    }
    

    【讨论】:

    • 太棒了!非常感谢。像魅力一样工作。对下面关于使用 oldStateEntity.apply(newState) 的 sn-p 感到好奇。我在尝试时没有看到可用的 .apply 方法...?
    • 这只是一个操纵实体状态的例子。因为我不知道你实际上对实体做了什么,所以我选择了一些通用的东西。
    猜你喜欢
    • 2020-03-01
    • 2015-11-25
    • 1970-01-01
    • 2021-03-28
    • 2018-11-30
    • 2019-02-19
    • 2018-06-29
    • 1970-01-01
    • 2018-01-08
    相关资源
    最近更新 更多