The error you might have looks like this:
GRAVE: Servlet.service() for servlet [testDispatcher] in context with path [/secondtest] threw exception [Request processing failed; nested exception is org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.test.anotated.ArtData.colors, no session or session was closed] with root cause org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.test.anotated.ArtData.colors, 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.initialize(AbstractPersistentCollection.java:368) at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111) at org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:272) at com.test.controller.GetArtController.helloWorld(GetArtController.java:38) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
I have found a good explanation of the why on a webpage:
"This error means that you’re trying to access a lazily-loaded property or collection, but the hibernate session is closed or not available . Lazy loading in Hibernate means that the object will not be populated (via a database query) until the property/collection is accessed in code. Hibernate accomplishes this by creating a dynamic proxy object that will hit the database only when you first use the object. In order for this to work, your object must be attached to an open Hibernate session throughout it’s lifecycle."
That is pretty nice! :)
The solution I've found in many web pages and forums is to force Hibernate to perform an Eager fetching by using fetch = FetchType.EAGER on the collection of the entity class. Once again, if you are building real world applications this kind of quickfix will not work.
For example, if your entity has one collection of objects (let's say a List<MyObject>), and each one of this objects has more than one collection of objects (let's say 2 or 3 List<String>); writing fetch = FetchType.EAGER next to each collection will probably carry you to have the javax.persistence.PersistenceException: org.hibernate.HibernateException: cannot simultaneously fetch multiple bags. Now, instead of trying to fix our brand new bug, lets try to fix our configuration to avoid having the first LazyInitializationException in a clean way.
How to avoid the LazyInitializationException:
All you need is to mantain the session of your sessionFactory open while the processing the request. This is possible by adding an OpenSessionInViewFilter filter in your web.xml that will bind the session to the thread of the entire processing of the request.
Here is an example of an web.xml file, we are defining the filter on lines 17-20 and doing the mapping it to all the URLs of the application on lines 22-25.
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Spring Web MVC Application</display-name> <!-- Listener to create the Spring Container shared by all Servlets and Filters --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:META-INF/spring/spring-master.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>testDispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>testDispatcher</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping> </web-app>
By doing this, the filter will mantain the session opened (during the request handling) and allow the Lazy fetching.
Try this sample project:
I did this little sample spring-mvc / hibernate project (using eclipse) if you want to see the complete configuration and test its execution.
You can download the project and all needed jars (14.3 M)
hibernate-sample.zip
or just the project with an empty \war\WEB-INF\lib directory (23 K)
hibernate-sample2.zip
To run this example you must have already a database installed and tomcat configured:
- Unzip the file with the project
- Import it to eclipse
- Edit the src/META-INF/spring/spring-datasource.xml to match your database (I have used Postgresql in this example)
- Run it whith Run on Server (if the option Run on Server don't appear read the next steps)
- enjoy :)
If Run on server option don't appear
- Rightclic on the project
- Choose properties
- Choose Project Facets
- Select "Dynamic Web Module" and Java and then clic on "Further Configuration" available.
- Set the "Content directory" as war and don't check the generate.xml option
- click OK
- Done!
Now if the project is running you can go to the URL http://localhost:8080/hibernate-sample/ and see this.
4 commentaires:
Thanks a lot! It was very-very helpful.
Thanks a lot! Your resolve is very helpful.
What about the hibernate 4. Id does not work for me. Do you know something about that?
Hibernate 4
Spring 4
Regards[]
Felipe
Holdem or Foldem and two Teen Patti video games scaled up final year. But total, there have been extra video games losing downloads than rising them. Playtika’s WSOP and Zynga Poker proceed to dominate the sub-genre although rising at beneath the market fee. At the identical time, video games likeTexas Hold'em Poker and Poker 온라인 카지노 Atrix grew significantly sooner.
Enregistrer un commentaire