为Hibernate管理的POJO提供Spring AOP建议 [英] Spring AOP Advice for Hibernate managed POJO

查看:115
本文介绍了为Hibernate管理的POJO提供Spring AOP建议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父子关系,比如订单到订单项目,我在域模型中表示如下:

  public class Order {
private int id;
私人套餐< OrderItem> orderItems = new HashSet< OrderItem>();

public int getId(){
return id;
}

public void add(OrderItem orderItem){
orderItems.add(orderItem);
}
}

公共类OrderItem {
private int id;

public int getId(){
return id;
}

}

我用Hibernate ,使用这样的映射:

 < class name =Ordertable =ORDERS> 
< id name =idcolumn =ORDER_IDaccess =field>
< generator class =native/>
< / id>
< set name =orderItemstable =ORDERS_TO_ITEMSaccess =fieldcascade =all>
< key column =ORDER_ID/>
< / set>
< / class>

< class name =OrderItemtable =ORDER_ITEMS>
< id name =idcolumn =ITEM_IDaccess =field>
< generator class =native/>
< / id>
< / class>

现在这个工作非常好。为了将订单项添加到订单中,例如在Spring Controller方法中,我可以通过一种简单而干净的方式实现:

  Order order = orderRepository.findById(orderId); 
OrderItem item = new OrderItem();
order.add(item);

完成。我甚至在我的Bean定义文件中设置了OpenSessionInViewInterceptor,所以只要控制器方法完成,Order Item就会被持久化。



问题是我想立即调用 item.getId(),但当 order.add(item)方法返回时,事务具有尚未提交,并返回零。最好的做法似乎是创建一个事务服务方法,我这样做:

  Order order = orderRepository.findById(订单ID); 
OrderItem item = new OrderItem();
orderService.addItem(order,item)

现在项目。 getId()立即返回生成的ID。



我遇到的问题是 orderService.addItem order.add(item)方法外,c $ c>方法没有任何用处。我想知道我如何摆脱它。



我的问题是,我怎么可能使 order.add (item)方法transactional

我看到它的唯一方法,与Hibernate会话交互的orderRepository必须返回一个Spring AOP或AspectJ代理,它的 add(item)方法我可以在我的Bean定义文件中声明为事务性。



我将如何能够返回这样的Spring托管代理订单?我可以通过覆盖Hibernate的 Interceptor.onLoad 方法来做到吗?



是否有其他方法可以创建订单,一个具体的实现,与春季交易顾问有关?



我知道我实施的服务可能是最实用的解决方案,但我真的很想知道我可以如何将AOP建议附加到Hibernate持久化的POJO实体中。

/static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-atconfigurablerel =nofollow>使用AspectJ向Spring依赖注入域对象一>。我有构建时间的可执行示例和加载时间编织可在github上获得。

I have a parent-child relationship, such as Order to Order Item, which I have represented in the domain model like this:

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;
    }

}

I am persisting these entities with Hibernate, using a mapping like this:

<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>

This is working very nicely now. To add an Order Item to an Order, for example in a Spring Controller method, I can do it in a simple and clean way:

Order order = orderRepository.findById(orderId);
OrderItem item = new OrderItem();
order.add(item);

Done. I even set-up the OpenSessionInViewInterceptor in my Bean Definition file, so as soon as the controller method completes, the Order Item is persisted.

The issue is I would like to call item.getId() right away, but when the order.add(item) method returns, the transaction has not yet been commited, and zero is returned. The best practice seems to be creating a transactional service method, and I did it like this:

Order order = orderRepository.findById(orderId);
OrderItem item = new OrderItem();
orderService.addItem(order, item)

Now item.getId() returns the generated ID right away.

The issue I have is the orderService.addItem method serves no purpose other than to wrap the order.add(item) method in a transaction. I would like to know how I can get rid of it.

My question is, how can I possibly make the order.add(item) method transactional?

The only way I see it, the orderRepository interacting with the Hibernate session must return a Spring AOP or AspectJ proxy, whose add(item) method I can declare as transactional in my Bean Definition file.

How would I be able to return such a Spring managed proxy Order? Can I do it by overriding Hibernate's Interceptor.onLoad method?

Is there any other way to make the Order, a concrete implementation, be associated with a Spring Transaction Advisor?

I know the service I implemented is probably the most practical solution, but I am really curious to know how I can attach AOP Advice to a Hibernate persisted POJO entity.

解决方案

What you're looking for is "Using AspectJ to dependency inject domain objects with Spring". I have executable examples of both build-time and load-time weaving available on github.

这篇关于为Hibernate管理的POJO提供Spring AOP建议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆