I currently mark collections in entity beans as eager to avoid getting a lazy initialization exception when I try to access the collection properties after loading the bean with the EntityManager.
If I instead leave the collection as lazy loading, how do I keep a session open? I thought about trying @Transactional, but even if that worked I wouldn't want to do it because it doesn't seem right to leave a transaction open over a long method.
Now, I haven't used Spring, but I have used Hibernate in several different projects. The approach I settled on for the most recent project grew out of the Defensive Session Handling pattern (in conjunction with a servlet filter), and we are happy with it. You can find more design patterns here.
As others have said, you should read up on "open session in view" pattern, the basic idea of which is to have a hibernate session open for the full duration of processing http request. There are both hibernate specific and spring solutions - I used spring's before and it works fine.
In the question you mention that you don't want to have transaction open for a long time. For most of the people this is not an issue because each request is processed relatively quickly. However if in your case it is indeed impossible this pattern will not work for you. Can you elaborate on why you don't want the transactions kept open?
One final option which seems to of been missed is you can build your object graph based on your use-case by using a JOIN.
This will result in the object being initialized, i.e the will not be a proxy.
Use this approach if you are in control of the client (i.e you not creating open service publishing an api) because you need to know what state is being touched when the session is closed because the transaction has closed.
When you leave a session open that has read some data, you will leave that transaction open. Long running transactions aren't that big of a problem (although that might depend on your database) what really causes problems are locks hold for a long time, but these might only get created once you actually change data in the database. Again this depends on your database.
Are you using Spring's HibernateTemplate? It will manage the session for you I believe. Alternatively if you are on Hibernate 3.0.1 or above, Spring should still be able to manage the session for you.
There is a SpringSource blog entry that describes how to set this up. I've included an extract below:
https://www.hibernate.org/43.html
Basically, you have a few options.
-You can use the "open session in view" pattern where you use a filter/interceptor/AOP - style logic to open a session when server side logic begins, and close it when it's through.
-You could implement conversations spanning several request-response cycles.
A plain old Servlet Filter is the easiest.