【发布时间】:2015-11-27 14:58:16
【问题描述】:
我有一个遗留数据库,我正在使用 JPA/Hibernate 开发一个 Spring MVC 应用程序。我的问题与复合主键的生成有关。一个主键的例子是这样组成的:
序列号、年份、OrderID、LineId
LineId 将根据 Serial、Year 和 LineId 的每个元组的 max(LineId) 生成。
我想过以下几种方式:
-
PrePersist 侦听器:这意味着侦听器必须访问存储库,甚至可能具有对其他实体的引用才能获得下一个 id。编辑:休眠文档说:
A callback method must not invoke EntityManager or Query methods!。 https://docs.jboss.org/hibernate/orm/4.0/hem/en-US/html/listeners.html#d0e3013 - 自定义生成器:我还没有找到一个示例来说明如何访问实体的实例来检索我需要进行正确选择的属性。
- 服务层:太冗长了。
- 覆盖 Spring 的数据的 JPA 存储库 save() 方法实现:在这种情况下,我们可以访问实体的实例属性。
实现此目的的正确方法是什么?谢谢
【问题讨论】:
-
我建议在存储库中使用 save 方法,如果每次保存都通过此方法。您只需要强制在存储实体时在任何地方都使用此方法。这就是 DAO/repository 模式的力量——它使您可以修改 entityManger 的标准行为以满足您的需求。
-
拥有复合主键是一个非常糟糕的主意,因此理想情况下,您应该返回并在旧数据库中添加一个 ID 列,并将当前复合键设为唯一索引。不幸的是,这个世界通常远非理想,但您当前的用例超出了 JPA 直接支持的 JPA 功能的范围。如果其他应用程序正在向表中插入数据,则没有好的解决方案。如果您的应用程序是数据库的唯一客户端,那么我将使用工厂来创建实体(带有 id),并像 Table/Sequence 生成器那样预先分配 Id。
标签: java spring hibernate spring-mvc jpa