事务类中的JPA不必要的用户类

Posted

技术标签:

【中文标题】事务类中的JPA不必要的用户类【英文标题】:JPA Unnecessary User class inside Transaction class 【发布时间】:2020-08-09 04:35:33 【问题描述】:

用户类

@Entity
class User 
    @OneToMany
    List<Order> orders;

订单类

@Entity
class Order    
    @ManyToOne
    User user;

    @OneToOne
    Transaction transaction 

事务类

@Entity
class Transaction 
    @OneToOne
    Order order;

    @ManyToOne
    User user; // Do you think this is necessary?

    void makeTransaction(long orderId)
        //Here I can easily get user object using orderId, right?
    

我对 Hibernate 很陌生。在我的项目中,当我无论如何要通过 Order 对象获取 User 对象时,我不明白为什么在 Transaction 类中添加了 User 用户属性..

那么,上面的Transaction类设计错了吗?或者它会在以后产生任何问题?

【问题讨论】:

不要认为有必要,因为 Transaction 直接链接到 Order 而不是用户。您将以这种方式访问​​事务(用户->订单->事务),但不是相反。即使您不添加用户,您仍然可以通过 Transaction.getOrder() 将用户链接到事务。获取用户()。所以认为再次链接 Transaction 和 User 是多余的。 【参考方案1】:

这取决于您的业务需求和业务需求。

乍一看,它似乎完全是多余的(在双方,数据库(冗余 FK)和 OO 方面(冗余引用)。

但这里没有告诉我,订单中的用户和交易中的用户实际上是相同的......

正如您解释的那样,“似乎”是相同的,但我个人不知道。因此,如果两个用户都可以“不同”,则此模型有效。

现在,如果我们假设用户在两个概念中始终相同,并且您有这个用例:load transactions by some criteria (timestamp, priority, whatever) "owns" by a specific user 如果交易中没有任何“用户”信息,您必须遍历他的所有订单并过滤/恢复您需要的交易。 有了里面的用户信息,您可以直接访问事务表(您甚至可以避免急切地加载 Order 或仅使用投影 DTO)。

现在也许不是在User 上保留hard reference,而是在其上保留一个轻量级引用:private Long userId,从而降低循环依赖问题的风险。

现在记住这一点 -> 它仍然是冗余。

当您对模型应用一些非规范化时,会发生关系建模冗余,有时它只是必需的(性能方面、用例需要、投影需要......)。

如果您有意识并同意这一点,那没关系。只需处理可能发生的Consistency 问题并准备好处理该属性即可。

【讨论】:

嗨,首先,感谢您的回复..我明白了您的观点..但最后,我很困惑...我应该将 User 保留在 Transaction 类中吗?对于上述情况,您会怎么做。你会将该用户保留在事务类中吗? 我会很高兴,如果你能告诉我你对这个帖子的看法,这里:***.com/questions/61497853/… 正如我所说的是同一用户吗?如果是...您的用例中是否需要这种冗余?如果是的话,仅通过“id”保持轻度参考是否可以接受...回答这些问题,您就会知道该怎么做;-) 好吧...订单取决于用户,交易取决于订单,因此间接地是,对于相同的交易和订单,它是同一用户。对于 UI,我有一个 DTO(比如 TransactionDTO),所以在 TransactionDTO 中,我已经有 UserDTO 来显示 UI 的 Rest 响应。我的查询仅与 DB 相关,与 UI 案例无关。对于轻型参考(例如 OneToMany 或 ManyToOne 关系),我们大多仅称为 Class,而不是 id ..(它可以是 DTO 或 Model 类) 那么,我可以删除 Transaction 类中的 User 依赖,对吧?

以上是关于事务类中的JPA不必要的用户类的主要内容,如果未能解决你的问题,请参考以下文章

多方类中的JPA Key生成

如何使用类中的 setters 方法将数据插入 JPA 实体表?

JPA实体类中的注解

在Spring Boot应用程序中的模型类中同时使用JPA和MongoDB注释的问题

默认情况下,不要使用Spring Data Rest和Jpa公开Entity类中的字段

Hibernate 从外部事务类中的 getCurrentPrice 返回 null