我有一个父子关系,例如Order to Order Item,我在域模型中代表了这样的关系:
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>
现在效果非常好。要将订单项添加到订单,例如在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代理,我的add(item)
方法可以在我的Bean定义文件中声明为事务性。
我如何能够返回这样的Spring托管代理订单?我可以通过覆盖Hibernate的Interceptor.onLoad
方法来实现吗?
还有其他方法可以使订单(具体实现)与Spring Transaction Advisor相关联吗?
我知道我实现的服务可能是最实用的解决方案,但我真的很想知道如何将AOP建议附加到Hibernate持久化POJO实体。
答案 0 :(得分:2)
您正在寻找的是"Using AspectJ to dependency inject domain objects with Spring"。我在github上提供了build-time和load-time编织的可执行示例。