Question

I have a many-to-one association set up like this, in the hbm.xml:

<many-to-one name="gigVenue"
class="blah.blah.xxx" fetch="select"
lazy="no-proxy" not-null="true" >
<column name="N_VENUE_ID" precision="18" scale="0" not-null="true" />
</many-to-one>

And I am using instrumentation to do true lazy loading.

BUT when I run a hql query with an inner join fetch to the other table, the property that should contain the object that is the other table's value, is left as null. Even though I can see the other table's value's object being created by hibernate.

Does anyone have any insight into this problem?

update:

from Gig g inner join fetch g.gigVenue gv where g.artistId = :artistId and  (g.territoryId = -1 or g.territoryId = :territoryId) order by g.gigDatetime desc

<set name="gigs" inverse="true" lazy="true" table="DSP_GIG" fetch="select">
<key>
<column name="N_VENUE_ID" precision="18" scale="0" not-null="true" />
</key>
<one-to-many class="blah.blah.Gig" />
</set>
Was it helpful?

Solution

Since you're using byte code instrumentation instead of association proxying (why?) you need to specify "fetch all properties" in your query:

from Gig g fetch all properties ... 

Details are here

Update: Your gigVenue mapping is setting lazy to no-proxy. What that means is that property will be NULL until its first accessed via getter method. This is done using byte-code instrumentation and is not something that is commonly used. Using HQL join fetch will NOT populate such a property; you have to explicitly specify fetch all properties as I described above.

Consider setting lazy="proxy" instead (that's actually the default for many-to-one) which will initialize your property with a proxy object containing gigVenue identifier during the initial select, then retrieve the actual entity once you access one of GigVenue's methods. Using join fetch in HQL will also work in this case, fetching full GigVenue instance during the initial select.

On that note, setting fetch="select" is also questionable; you're most likely better off leaving it at the default join setting to enable using outer joins for fetching.

OTHER TIPS

Instrumentation does not really affect queries and how they work. Why exactly are you doing the fetch in the query? Are you trying to speed things up?

And also a small question, just in case, how do you know the value is null? is that via the java debugger or is that by actually calling the "get" method? With instrumentation, the field will typically be null, until you actually ask for the field.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top