Spring AOP Советы для Hibernate-управляемого POJO - PullRequest
1 голос
/ 06 октября 2011

У меня есть отношения родитель-потомок, такие как Порядок заказа, который я представил в модели предметной области следующим образом:

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

Готово. Я даже настроил OpenSessionInViewInterceptor в своем файле определения компонента, поэтому, как только метод контроллера завершится, элемент заказа будет сохранен.

Проблема в том, что я хотел бы сразу вызвать item.getId(), но когда метод order.add(item) возвращается, транзакция еще не зафиксирована, и возвращается ноль. Лучше всего создается метод транзакционного сервиса, и я сделал это так:

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

Теперь item.getId() сразу возвращает сгенерированный идентификатор.

Проблема, с которой я столкнулся, заключается в том, что метод orderService.addItem не служит никакой другой цели, кроме как обернуть метод order.add(item) в транзакцию. Я хотел бы знать, как я могу избавиться от этого.

Мой вопрос: как я могу сделать метод order.add(item) транзакционным?

Единственный способ, которым я это вижу, это то, что orderRepository, взаимодействующий с сеансом Hibernate, должен возвращать прокси Spring AOP или AspectJ, чей метод add(item) я могу объявить как транзакционный в моем файле определения компонента.

Как я могу вернуть такой заказ Spring-прокси? Могу ли я сделать это путем переопределения метода Interceptor.onLoad в Hibernate?

Есть ли другой способ сделать Order, конкретную реализацию, связанным с Spring Transaction Advisor?

Я знаю, что реализованный мною сервис, вероятно, является наиболее практичным решением, но мне действительно любопытно узнать, как я могу подключить AOP Advice к персистентному объекту POJO в Hibernate.

1 Ответ

2 голосов
/ 06 октября 2011

То, что вы ищете, это "Использование AspectJ для добавления объектов домена в Spring с зависимостью" . У меня есть исполняемые примеры времени сборки и времени загрузки ткачества, доступные на github.

...