title: Spring AOP Advice for Hibernate managed POJO
body: <p>I have a parent-child relationship, such as Order to Order Item, which I have represented in the domain model like this:</p>
  
  <pre><code>public class Order {
      private int id;    
      private Set&lt;OrderItem&gt; orderItems = new HashSet&lt;OrderItem&gt;();
  
      public int getId() {
          return id;
      }
  
      public void add(OrderItem orderItem) {
          orderItems.add(orderItem);
      }
  }
  
  public class OrderItem {
      private int id;
  
      public int getId() {
          return id;
      }
  
  }
  </code></pre>
  
  <p>I am persisting these entities with Hibernate, using a mapping like this:</p>
  
  <pre><code>&lt;class name="Order" table="ORDERS"&gt;
      &lt;id name="id" column="ORDER_ID" access="field"&gt;
          &lt;generator class="native" /&gt;
      &lt;/id&gt;
      &lt;set name="orderItems" table="ORDERS_TO_ITEMS" access="field" cascade="all"&gt;
          &lt;key column="ORDER_ID" /&gt;
          &lt;many-to-many class="OrderItem" unique="true" column="ITEM_ID" /&gt;
      &lt;/set&gt;
  &lt;/class&gt;
  
  &lt;class name="OrderItem" table="ORDER_ITEMS"&gt;
      &lt;id name="id" column="ITEM_ID" access="field"&gt;
          &lt;generator class="native" /&gt;
      &lt;/id&gt;
  &lt;/class&gt;
  </code></pre>
  
  <p>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:</p>
  
  <pre><code>Order order = orderRepository.findById(orderId);
  OrderItem item = new OrderItem();
  order.add(item);
  </code></pre>
  
  <p>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.</p>
  
  <p>The issue is I would like to call <code>item.getId()</code> right away, but when the <code>order.add(item)</code> 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:</p>
  
  <pre><code>Order order = orderRepository.findById(orderId);
  OrderItem item = new OrderItem();
  orderService.addItem(order, item)
  </code></pre>
  
  <p>Now <code>item.getId()</code> returns the generated ID right away.</p>
  
  <p>The issue I have is the <code>orderService.addItem</code> method serves no purpose other than to wrap the <code>order.add(item)</code> method in a transaction.  I would like to know how I can get rid of it.</p>
  
  <p><strong>My question is, how can I possibly make the <code>order.add(item)</code> method transactional?</strong></p>
  
  <p>The only way I see it, the orderRepository interacting with the Hibernate session must return a Spring AOP or AspectJ proxy, whose <code>add(item)</code> method I can declare as transactional in my Bean Definition file.</p>
  
  <p>How would I be able to return such a Spring managed proxy Order?  Can I do it by overriding Hibernate's <code>Interceptor.onLoad</code> method?</p>
  
  <p>Is there any other way to make the Order, a concrete implementation, be associated with a Spring Transaction Advisor?</p>
  
  <p>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.</p>