我有一个遗留数据库,并且正在使用 JPA/Hibernate 开发 Spring MVC 应用程序。我的问题在于复合主键的生成。主键的示例如下:
序列号、年份、订单 ID、线路 ID
LineId 将根据 Serial、Year 和 LineId 每个元组的 max(LineId) 生成。
我考虑了以下几种方法:
<小时/>- PrePersist Listener:这意味着监听器必须访问存储库,甚至可能引用其他实体才能获取下一个 id。编辑:Hibernate 文档说:
回调方法不得调用 EntityManager 或查询方法!
。 https://docs.jboss.org/hibernate/orm/4.0/hem/en-US/html/listeners.html#d0e3013 - 自定义生成器:我还没有找到一个示例来说明如何访问实体的实例来检索进行正确选择所需的属性。
- 服务层:太冗长了。
- 重写 Spring 数据的 JPA Repository save() 方法实现:在本例中,我们可以在这里访问实体的实例属性。
实现此目的的正确方法是什么?谢谢
最佳答案
为了支持这一点,我经常使用域驱动设计技术,在将 OrderLine
关联到 Order
时,我可以控制这一点。
public class Order {
private List<OrderLine> lines;
// don't allow the external world to modify the lines collection.
// forces them to use domain driven API exposed below.
public List<OrderLine> getLines() {
return Collections.unmodifiableList( lines );
}
// avoid allowing external sources to set the lines collection
// Hibernate can set this despite the method being private.
private void setLines(List<OrderLine> lines) {
this.lines = lines;
}
public OrderLine addLine(String serial, Integer year) {
final OrderLine line = new OrderLine( this, serial, year );
lines.add( line );
return line;
}
public void removeLine(Integer lineId) {
lines.removeIf( l -> l.getId().getLineId().equals( lineId ) );
}
}
public OrderLine {
public OrderLine() {
}
OrderLine(Order order, String serial, Integer year) {
this.id = new OrderLineId( order.getLines().size() + 1, serial, year, order.getId() );
}
}
调用特殊 OrderLine
构造函数的唯一代码是从 Order
调用的,并且您确保始终委托(delegate)添加和删除 OrderLine
code> 实体通过聚合根,Order
。
这也意味着您只需要公开 Order
存储库,并且仅通过 Order
操作与 Order
关联的行,并且从来不直接。
关于java - PrePersist、自定义生成器或服务层中的 Spring JPA/Hibernate 复合 key 生成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32347429/