-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: merge() creates a CGLib proxy for many-to-one related entity
PostPosted: Fri Feb 01, 2008 8:49 pm 
Newbie

Joined: Fri Feb 01, 2008 8:07 pm
Posts: 2
I'm seeing some unexpected (may be totally correct) behavior when using merge() in Hibernate 3.2.

I have an entity, A, that has a many-to-one mapping to another entity, User.

<class name="A" table="a">
<id name="id" column="id">
<generator class="native"/>
</id>

<many-to-one name="user"
column="user_id"
class="User"
not-null="true"/>
...
</class>

<class name="User" table="user">
<id name="id" column="id" type="stringToLong" >
<generator class="native"/>
</id>
<property name="username"/>
...
</class>

I have a query to find a user by their username:

public User findByName(String username) {
Query query = getCurrentSession().createQuery("from User u "
+ "where u.username = :username");
query.setParameter("username", username);
return (User)query.uniqueResult();
}

This query returns a concrete User object, which is what I expect.

However, if in the same session I first do a merge() on an entity A for that User, then if I use the above findByName query, I get back a CGLib proxy (User$$EnhancerByCGLIB). This causes problems for me, because I'm using XStream, which does not seem to handle CGLib proxies gracefully.

I did some digging, and I found that merge() call is creating a proxy and storing it on StatefulPersistenceContext. Here is the stack trace:

addProxy():874, org.hibernate.engine.StatefulPersistenceContext
createProxyIfNecessary():259, org.hibernate.event.def.DefaultLoadEventListener
proxyOrLoad():191, org.hibernate.event.def.DefaultLoadEventListener
onLoad():103, org.hibernate.event.def.DefaultLoadEventListener
fireLoad():878, org.hibernate.impl.SessionImpl
internalLoad():846, org.hibernate.impl.SessionImpl
resolveIdentifier():557, org.hibernate.type.EntityType
resolve():379, org.hibernate.type.EntityType
initializeEntity():116, org.hibernate.engine.TwoPhaseLoad
initializeEntitiesAndCollections():854, org.hibernate.loader.Loader
doQuery():729, org.hibernate.loader.Loader
doQueryAndInitializeNonLazyCollections():236, org.hibernate.loader.Loader
loadEntity():1860, org.hibernate.loader.Loader
load():48, org.hibernate.loader.entity.AbstractEntityLoader
load():42, org.hibernate.loader.entity.AbstractEntityLoader
load():3044, org.hibernate.persister.entity.AbstractEntityPersister
loadFromDatasource():395, org.hibernate.event.def.DefaultLoadEventListener
doLoad():375, org.hibernate.event.def.DefaultLoadEventListener
load():139, org.hibernate.event.def.DefaultLoadEventListener
proxyOrLoad():195, org.hibernate.event.def.DefaultLoadEventListener
onLoad():103, org.hibernate.event.def.DefaultLoadEventListener
fireLoad():878, org.hibernate.impl.SessionImpl
get():815, org.hibernate.impl.SessionImpl
entityIsDetached():229, org.hibernate.event.def.DefaultMergeEventListener
onMerge():120, org.hibernate.event.def.DefaultMergeEventListener
onMerge():53, org.hibernate.event.def.DefaultMergeEventListener
fireMerge():677, org.hibernate.impl.SessionImpl
merge():661, org.hibernate.impl.SessionImpl

When the query executes it finds the User (and it is fully populated), but StatefulPersistenceContext.proxyForEntityPersister persister, EntityKey key, Object impl) finds a proxy for it and wraps it instead of returning the original implementation.

It seems like the User query should not be concerned with a merge() for an unrelated (from its perspective) domain object (entity A). Is that correct or is this expected behavior? If it is expected behavior is there a way for me to either safely remove the proxy or to unwrap the proxy? I tried Hibernate.initialize(Object), but the object is already "initialized".


Top
 Profile  
 
 Post subject:
PostPosted: Mon Feb 11, 2008 6:28 pm 
Newbie

Joined: Fri Feb 01, 2008 8:07 pm
Posts: 2
Perhaps one other interesting data point is that when I use update() the User object is not proxied. I'm going to dig through the source and see what the difference is; however, in this case I really do need merge() and not update(). Any help would be greatly appreciated.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.