【发布时间】:2011-10-05 23:40:58
【问题描述】:
我有一个父子关系,例如订单到订单项,我在域模型中表示如下:
public class Order {
private int id;
private Set<OrderItem> orderItems = new HashSet<OrderItem>();
public int getId() {
return id;
}
public void add(OrderItem orderItem) {
orderItems.add(orderItem);
}
}
public class OrderItem {
private int id;
public int getId() {
return id;
}
}
我用 Hibernate 持久化这些实体,使用如下映射:
<class name="Order" table="ORDERS">
<id name="id" column="ORDER_ID" access="field">
<generator class="native" />
</id>
<set name="orderItems" table="ORDERS_TO_ITEMS" access="field" cascade="all">
<key column="ORDER_ID" />
<many-to-many class="OrderItem" unique="true" column="ITEM_ID" />
</set>
</class>
<class name="OrderItem" table="ORDER_ITEMS">
<id name="id" column="ITEM_ID" access="field">
<generator class="native" />
</id>
</class>
现在效果很好。要将 Order Item 添加到 Order 中,例如在 Spring Controller 方法中,我可以用一种简单而干净的方式来完成:
Order order = orderRepository.findById(orderId);
OrderItem item = new OrderItem();
order.add(item);
完成。我什至在我的 Bean 定义文件中设置了 OpenSessionInViewInterceptor,因此一旦控制器方法完成,订单项就会被持久化。
问题是我想马上调用item.getId(),但是当order.add(item)方法返回时,事务还没有提交,返回零。最佳实践似乎是创建一个事务服务方法,我是这样做的:
Order order = orderRepository.findById(orderId);
OrderItem item = new OrderItem();
orderService.addItem(order, item)
现在item.getId() 立即返回生成的 ID。
我遇到的问题是orderService.addItem 方法除了将order.add(item) 方法包装在事务中之外没有其他用途。我想知道如何摆脱它。
我的问题是,我怎样才能使 order.add(item) 方法具有事务性?
我看到的唯一方式是,与 Hibernate 会话交互的 orderRepository 必须返回一个 Spring AOP 或 AspectJ 代理,我可以在我的 Bean 定义文件中将其 add(item) 方法声明为事务性。
我如何才能返回这样的 Spring 托管代理订单?我可以通过覆盖 Hibernate 的 Interceptor.onLoad 方法来做到这一点吗?
有没有其他方法可以让 Order(一个具体的实现)与 Spring Transaction Advisor 相关联?
我知道我实现的服务可能是最实用的解决方案,但我真的很想知道如何将 AOP Advice 附加到 Hibernate 持久化 POJO 实体。
【问题讨论】:
标签: hibernate spring domain-driven-design aspectj spring-aop