IndexedContainer and lazy loaded items problem

Hi!

I have quite a strange problem with IndexedContainer when using lazy loaded items.
First I create a container, add some container properties with addContainerProperty().

Now when I try to add a new item to the container with addItem(), no exception is thrown.
Anyway, if I try to print that item (using print()), I get NullPointerException like this:


java.lang.NullPointerException
	at com.vaadin.data.util.IndexedContainer$IndexedContainerProperty.getValue(IndexedContainer.java:1255)
	at com.vaadin.data.util.IndexedContainer$IndexedContainerProperty.toString(IndexedContainer.java:1331)
	at com.vaadin.data.util.IndexedContainer$IndexedContainerItem.toString(IndexedContainer.java:1122)
	at java.lang.String.valueOf(String.java:2826)
	at java.io.PrintStream.println(PrintStream.java:771)

The stack trace goes on but IMHO contains no valuable information.

I figured out this has something to do with the fact, that I’m using collections to be lazy loaded and
load them with Hibernate.initialize() before setting those items to container.
That’s because if I set those collections to be eagerly fetched,
all goes smoothly and my container is populated successfully.

Has anyone any knowledge of what is happening there?

Thanks in advance for all helpers!!

Hibernate does not support lazy loading across sessions. Therefore, if you use the normal session per request pattern, lazy loading does not work unless you first explicitly merge the entity before trying to lazy load its fields - which you cannot do (or would very seriously affect application performance) in many cases.

Note that this problem is not specific to Vaadin, but affects all systems using the session-per-request approach and Hibernate lazy loading. Hibernate has its reasons for interpreting the JPA standard this way, but it can make the life of web application developers hard.

EclipseLink does have some support for lazy loading across sessions.

Alternatively, you can use a session per application pattern, which does keep potentially a very large number of sessions open all the time.

Thanks for your answer Henri!

I think I’ve noticed the points you mentioned but can not be sure because the problem still occurs.

Actually I initialize those lazy collections right after finding the entity from database and after finishing that transaction (transaction per method, so is the session?) I pass the entity containing the collection to the method that is supposed to initialize the container.

So does it still matter somehow that my entity has been lazy but before even creating the container it has been fully initialized?

As far as I understand the problem might be

  • in application architecture - after transaction has been executed your code is still trying to call uninitialized bean. To avoid this you should initialize all lazy initialized beans before transaction has finished either by accessing bean within transaction(it will be initialized automatically) or use join fetch construction in you JPA queries.
  • if application architecture looks fine you should sometimes when needed to use join fetch construction to avoid exception
  • the last variant when it is too late to change anything you can create DeproxyUtil class that will explicitly re-associate lazy initialized bean with persistent context and deproxy it.

See in separate
thread