Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I think what's happening here is an interesting interaction between the first level cache (stored in Hibernate's Session instance) and having different <code>FetchType</code> on related objects.</p> <p>When you load <code>Customer</code>, it gets put in to the <code>Session</code> cache, along with any objects that are loaded with it. This includes a proxy object for the <code>OrderItem</code> object, because you've got <code>FetchType.LAZY</code>. Hibernate only allows one instance to be associated with any particular ID, so any further operations that would be acting on the <code>OrderItem</code> with that ID <strong><em>would always be using that proxy</em></strong>. If you asked the same <code>Session</code> to get that particular <code>OrderItem</code> in another way, as you are by loading an <code>Order</code> containing it, that <code>Order</code> would have the proxy, because of Session-level identity rules.</p> <p>That's why it 'works' when you reverse the order. Load the <code>Order</code> first, it's collection is <code>FetchType.EAGER</code>, and so it (and the first level cache) have fully realized instances of <code>OrderItem</code>. Now load a <code>Customer</code> which has it's <code>lastItem</code> set to one of the already-loaded <code>OrderItem</code> instances and presto, you have a real <code>OrderItem</code>, not a proxy.</p> <p>You can see the identity rules documented in the <a href="http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/transactions.html#transactions-basics-identity" rel="nofollow">Hibernate manual</a>: </p> <blockquote> <p>For objects attached to a particular Session... JVM identity for database identity is guaranteed by Hibernate.</p> </blockquote> <p>All that said, even if you get an <code>OrderItem</code> proxy, it should work fine as long as the associated <code>Session</code> is still active. I wouldn't necessarily expect the proxy ID field to show up as populated in the debugger or similar, simply because the proxy handles things in a 'special' way (ie, it's not a POJO). But it should respond to method calls the same way it's base class would. So if you have an <code>OrderItem.getId()</code> method, it should certainly return the ID when called, and similarly on any other method. Because it's lazily initialized though, some of those calls may require a database query.</p> <p>It's possible that the only real problem here is simply that it's confusing to have it so that any particular <code>OrderItem</code> could be a proxy or not. Maybe you want to simply change the relationships so that they're either both lazy, or both eager?</p> <p>For what it's worth, it's a bit odd that you've got the ManyToMany relationship as <code>EAGER</code> and the ManyToOne as <code>LAZY</code>. That's exactly the reverse of the usual settings, so I would at least think about changing it (although I obviously don't know your entire use case). One way to think about it: If an <code>OrderItem</code> is so expensive to fetch completely that it's a problem when querying for <code>Customer</code>, surely it's also too expensive to load <em>all</em> of them at once? Or conversely, if it's cheap enough to load all of them, surely it's cheap enough to just grab it when you get a <code>Customer</code>?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload