问题描述:

It appears that if you use a selectManyCheckbox backed by a set that is proxied by hibernate you will run into problems with the dreaded LazyInitializationException. This has nothing to do with the state of the backing bean!

After debugging Mojarra 2.1 I discovered that if you do not included the attribute collectionType it will attempt to clone the backing value class in the process validations phase, which in my case is PersistentSet. Of course adding any value to this will cause a LazyInitializationException.

My question is whether you think this is reasonable behaviour at the process validations phase?

A better algorithm to clone the collection class would be to look at the interface and instantiate a known class from java.util.

网友答案:

Thats exactly the point! It has nothing todo with the session state... I've ran into this problem and I was able to solve it by adding the following within my component (in my case a selectManyMenu):

<f:attribute name="collectionType" value="java.util.ArrayList" />;
网友答案:

Thanks for the hint to use the collectionType attribute for h:selectMany tags to prevent the LazyInitializationException.

However, instead of flaming about it in an inappropriate forum, how about learning what's new in JSF 2.0, and posting a full example of this problem and how to fix it?

Groundwork:

  • Mojarra 2.1 is the JSF 2 Reference Implementation (see What is Mojarra)
  • h:selectManyCheckbox VLD documentation describes how to use the collectionType attribute (new in JSF 2.0)
  • this problem affects validation of h:selectManyCheckbox, h:selectManyListBox, and h:selectManyMenu tags

Stack Trace of this error:

Feb 04, 2013 1:20:50 PM com.sun.faces.lifecycle.ProcessValidationsPhase execute WARNING: failed to lazily initialize a collection, no session or session was closed org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383) at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375) at org.hibernate.collection.AbstractPersistentCollection.readSize(AbstractPersistentCollection.java:122) at org.hibernate.collection.PersistentBag.isEmpty(PersistentBag.java:255) at javax.faces.component.UIInput.isEmpty(UIInput.java:1257) at javax.faces.component.UIInput.validateValue(UIInput.java:1144) at javax.faces.component.UISelectMany.validateValue(UISelectMany.java:579)

Example adding collectionType to fix this error (I am using a custom validator):

<h:selectManyListbox value="${technologyService.entity.associatedLabs}"
collectionType="java.util.ArrayList">
<f:validator validatorId="selectManyListboxValidator" />
<f:attribute name="maxItems" value="5" />
<f:selectItems value="${metadataService.activeLabSelectItems}" />
</h:selectManyListbox>
相关阅读:
Top