-
1. Re: Hibernate first level cache is destroing my life
qwertywin Jun 18, 2009 12:26 AM (in response to jean.baldessar)set the manyToOne fetch type to eager
@
ManyToOne(fetch = FetchType.EAGER)
if you are working with it in the same transaction then it doesnt matter, unless you are trying to do some sort of object equivalence..
e.g.
also you might want to do this instead
UserEntity user = em.createQuery("from UserEntity as user where user.id=1").getSingleResult(); Stuff stuff = user.getStuff();
at which point hibernate will go and snatch the lazy proxy anyway.
-
2. Re: Hibernate first level cache is destroing my life
amitev Jun 18, 2009 12:28 AM (in response to jean.baldessar)Try marking the first query as read-only.
-
3. Re: Hibernate first level cache is destroing my life
swd847 Jun 18, 2009 12:38 AM (in response to jean.baldessar)I have been in this situation before. The trick is to use bytecode enhancement instead of proxies. First you need to instrument your code:
<target name="instrument" depends="compile"> <taskdef name="instrument" classname="org.hibernate.tool.instrument.javassist.InstrumentTask"> <classpath> <fileset dir="lib"> <include name="*.jar" /> </fileset> </classpath> </taskdef> <instrument verbose="false" > <fileset dir="${jar.dir}/com/myproject/entities"> <include name="*.class" /> </fileset> </instrument> </target>
Then you need to annotatate your association with @LazyToOne(NO_PROXY), and hibernate should stop giving you proxies.
-
4. Re: Hibernate first level cache is destroing my life
kragoth Jun 18, 2009 3:19 AM (in response to jean.baldessar)Hi Jean,
We've come across this same issue in our application I'll go through what I
think
we did to solve it. Was a while ago :PJust a note on the other posts:
First of all, making the relationship EAGER is not a good option, and never is in any larger application. It's also not really a good practice to get into. You don't want to be flooding your DB with queries and loading data that you don't need.
Second, I don't think making the query read only will solve your problem. You can try but I'm pretty sure it will have no effect. Could be wrong about this, but I think we tried this and it didn't change anything.
Third, bytecode enhancement seems like a rather large change to fix a relatively small problem.
Ok, the way we solved the problem (at least as far as I can remember) is this.
Using your example.
- Query out UserEntity without loading stuff
- Now when you need stuff, Query out Stuff (NOT UserEntity fetch stuff) just query Stuff where UserEntity='value' //assumes you have a back pointer
- Next, do a
Hibernate.initialize(UserEntity.stuff) //This should not cause any queries to happen as your previous query loaded stuff
This solution is based on the assumption that you are in the same session when both queries occur and when the call to Hibernate.initialize happens.
If this doesn't work let me know and I'll try take another look at our codebase to see if I missed something.
Of course alternatively you could just make sure that your two queries don't happen in the same session and then it would just work for you. But if you are using SEAM's extended persistence context then I can't help you there.