You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@click.apache.org by Doychi <do...@doychi-dina.ath.cx> on 2009/10/20 11:12:35 UTC

Click 2, Spring and JPA Lazy Initialisation Error

Hi all,

I'm hoping someone can help me with a lazy initialisation error.  The error
I am getting is:

    failed to lazily initialize a collection of role ... no session or
session was closed

I am using Click 2's SpringClickServlet configured in the web.xml and JPA.

This is my web.xml, which seems to load everything okay.


<web-app>
	<listener>
	
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<servlet>
		<servlet-name>SpringClickServlet</servlet-name>
		<servlet-class>au.org.pheno.f1.click.SpringClickServlet</servlet-class>
		<load-on-startup>0</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>SpringClickServlet</servlet-name>
		<url-pattern>*.htm</url-pattern>
	</servlet-mapping>
</web-app>


The page, which was taken from my login page, is trying to load a user
(principal) and display its roles to test the lazy loading issue.


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package au.org.pheno.f1.test.pages;

import javax.annotation.Resource;

import org.apache.click.Page;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import au.org.pheno.f1.domain.attendees.Principal;
import au.org.pheno.f1.repository.attendees.IPrincipalRepository;

/**
 * The login screen provides a user a way to login to the system.
 * 
 * @author doychi
 */
@Component("au.org.pheno.f1.test.pages.LoginPage")
public class LoginPage extends Page {

    private static final String TITLE = "Test Page";
    public String msg = "";
    private IPrincipalRepository repository;
    private Logger log = Logger.getLogger(LoginPage.class);
    public Principal principal;

    private Logger getLogger() {
	return log;
    }

    /**
     * Retrieve the title
     * 
     * @return the title
     */
    public String getTitle() {
	return TITLE;
    }

    /**
     * Set the principal repository to use for the page.
     * 
     * @param principalRepository
     *            the repository to use
     */
    @Resource(name = "principalRepository")
    public void setPrincipalRepository(IPrincipalRepository
principalRepository) {
	if (getLogger().isDebugEnabled()) {
	    getLogger().debug("IPrincipalRepository set");
	}

	this.repository = principalRepository;
    }

    public IPrincipalRepository getPrincipalRepository() {
	return repository;
    }

    @Override
    public void onInit() {
	super.onInit();
	principal = repository.principalByLogin("admin");
	getLogger().info(principal.toString());
    }

}


The principal repository looks like this:


package au.org.pheno.f1.repository.attendees.jpa;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.log4j.Logger;
import org.springframework.dao.DataAccessException;
import org.springframework.security.AuthenticationServiceException;
import org.springframework.security.BadCredentialsException;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import au.org.pheno.f1.domain.attendees.Principal;
import au.org.pheno.f1.domain.attendees.Role;
import au.org.pheno.f1.repository.Repository;
import au.org.pheno.f1.repository.WrongNumberOfResultsReturnedException;
import au.org.pheno.f1.repository.attendees.IPrincipalRepository;

/**
 * Class description
 * 
 * 
 * @version Enter version here..., 07/12/26
 * @author Enter your name here...
 */
@Component("principalRepository")
@Transactional(readOnly = true)
public class PrincipalRepository extends Repository<Principal> implements
	IPrincipalRepository {

    private String LOGIN_TAG = "usr";
    private static final Logger log = Logger
	    .getLogger(PrincipalRepository.class);
    private static final String FILTER_OP_BOOLEAN = " = ";
    private static final String FILTER_OP_INTEGER = " = ";
    private static final String FILTER_OP_STRING = " LIKE ";
.
.
.
    /**
     * {@inheritdoc}
     */
    @Override
    public Principal principalByLogin(String login) {
	Principal result;
	String query = "SELECT principal FROM PrincipalJpa principal WHERE "
		+ "principal.username = :" + LOGIN_TAG;
	Map<String, Object> params = new TreeMap<String, Object>();

	params.put(LOGIN_TAG, login);

	result = (Principal) readOne(query, params);

	return result;
    }
.
.
.
}


The error appears to be thrown when my template tries to list the roles:


<html>
<body>
<p class="errorMessage">
    $!msg
</p>
${principal.firstName} ${principal.lastName}
#foreach( $role in $principal.roles)
	$role.name
#end
</body>
</html>


Does anyone have any thoughts on what I'm doing wrong?

Thanks,
--
Doychi
-- 
View this message in context: http://n2.nabble.com/Click-2-Spring-and-JPA-Lazy-Initialisation-Error-tp3857539p3857539.html
Sent from the click-user mailing list archive at Nabble.com.

Re: Redirect some users to custom handlers

Posted by Bob Schellink <sa...@gmail.com>.
Hi Hans,

onSecurityCheck is a good place for this sort of stuff. Note that Click will respect the 
forward/redirect you set in onInit when rendering the page. See this Page execution flow diagram for 
  detail:

http://incubator.apache.org/click/docs/user-guide/html/ch02s02.html#activity-diagram

kind regards

bob

hans@welinux.cl wrote:
> Hi,
> 
> Responding to myself, i made it work: 
> 
> Override onSecurityCheck, set the Forward page to the page you like to go (Not Redirect) and then return false.
> 
> Hans
> 
> ----- hans@welinux.cl escribió:
> 
>> Hi,
>>
>> I have a common url: home.htm, that i can't change, it always go to a
>> specific click page handler.
>>
>> In this page there are some users that i need to redirect to a custom
>> page depending on the user type. I tried setting redirect and forward
>> in the onInit() method and then returning, but i doesn't work.
>>
>> Looking at click servlet code, i've noticed it's not checking if in
>> the onInit() method there are redirects or forwards setted.
>>
>> Is there some specific way to achieve this with click without writing
>> filters.
>>
>> Thanks
>> Hans
> 


Re: Redirect some users to custom handlers

Posted by ha...@welinux.cl.
Hi,

Responding to myself, i made it work: 

Override onSecurityCheck, set the Forward page to the page you like to go (Not Redirect) and then return false.

Hans

----- hans@welinux.cl escribió:

> Hi,
> 
> I have a common url: home.htm, that i can't change, it always go to a
> specific click page handler.
> 
> In this page there are some users that i need to redirect to a custom
> page depending on the user type. I tried setting redirect and forward
> in the onInit() method and then returning, but i doesn't work.
> 
> Looking at click servlet code, i've noticed it's not checking if in
> the onInit() method there are redirects or forwards setted.
> 
> Is there some specific way to achieve this with click without writing
> filters.
> 
> Thanks
> Hans

-- 
Hans Poo, WeLinux S.A. http://www.welinux.cl
Oficina: 697.25.42, Celular: 09-319.93.05
Bombero Ossa # 1010, Santiago


Redirect some users to custom handlers

Posted by ha...@welinux.cl.
Hi,

I have a common url: home.htm, that i can't change, it always go to a specific click page handler.

In this page there are some users that i need to redirect to a custom page depending on the user type. I tried setting redirect and forward in the onInit() method and then returning, but i doesn't work.

Looking at click servlet code, i've noticed it's not checking if in the onInit() method there are redirects or forwards setted.

Is there some specific way to achieve this with click without writing filters.

Thanks
Hans

Re: Click 2, Spring and JPA Lazy Initialisation Error

Posted by Bob Schellink <sa...@gmail.com>.
Hi Doychi,

Did a small implementation of the "Open EntityManager In View" pattern using Spring 2.5.6 and 
Hibernate 3.3.2 which is used as the JPA provider.

Here are the details:

- WEB-INF/web.xml:

   <filter>
     <filter-name>jpaFilter</filter-name>
     <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
   </filter>

   <filter-mapping>
     <filter-name>jpaFilter</filter-name>
     <url-pattern>/*</url-pattern>
   </filter-mapping>

   <listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>

   <servlet>
     <servlet-name>ClickServlet</servlet-name>
     <servlet-class>org.apache.click.extras.spring.SpringClickServlet</servlet-class>
      <load-on-startup>0</load-on-startup>
   </servlet>


- src/conf/persistence.xml (mostly empty as setup is done by spring)

   <persistence-unit name="persistence"
     transaction-type="RESOURCE_LOCAL">
   </persistence-unit>


- WEB-INF/applicationContext.xml (meat is defined in spring config)

     <context:component-scan base-package="com.mycorp" 
scope-resolver="org.apache.click.extras.spring.PageScopeResolver"/>

     <bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
         <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
         <property name="url" value="jdbc:hsqldb:mem:demoDB"/>
         <property name="username" value="sa"/>
         <property name="password" value=""/>
     </bean>

     <bean id="entityManagerFactory" 
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
         <property name="dataSource" ref="myDataSource"/>
         <property name="jpaVendorAdapter">
             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                 <property name="databasePlatform" value="org.hibernate.dialect.HSQLDialect"/>
                 <property name="showSql" value="true" />
                 <property name="generateDdl" value="true" />
             </bean>
         </property>
     </bean>

     <tx:annotation-driven transaction-manager="transactionManager"/>

     <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

     <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
        <property name="dataSource" ref="myDataSource"/>
     </bean>


- MyContactService class:

@Component
@Transactional
public class MyContactService implements ContactService {

     @PersistenceContext
     private EntityManager entityManager;

     public void setEntityManager(EntityManager entityManager) {
         this.entityManager = entityManager;
     }

     public List<Contact> getAll() {
         return entityManager.createQuery("from Contact").getResultList();
     }
}


- And finally the ContactPage:

@Component
public class ContactEditPage extends Page {

     @Resource(name="myContactService")
     private ContactService contactService;

     ...
}


Here is a snippet from the log file (add log4j.xml to the classpath to view detailed logs):

DEBUG OpenEntityManagerInViewFilter - Using EntityManagerFactory 'entityManagerFactory' for 
OpenEntityManagerInViewFilter
DEBUG DefaultListableBeanFactory - Returning cached instance of singleton bean 'entityManagerFactory'
DEBUG OpenEntityManagerInViewFilter - Opening JPA EntityManager in OpenEntityManagerInViewFilter
[Click] [debug] GET http://localhost:9999/click-jpa-example/contact-edit.htm
DEBUG DefaultListableBeanFactory - Creating instance of bean 'contactEditPage'
DEBUG InjectionMetadata - Processing injected field of bean 'contactEditPage': ResourceElement for 
private com.mycorp.service.ContactService com.mycorp.ContactEditPage.contactService
DEBUG DefaultListableBeanFactory - Returning cached instance of singleton bean 'myContactService'
DEBUG DefaultListableBeanFactory - Finished creating instance of bean 'contactEditPage'

....

DEBUG AnnotationTransactionAttributeSource - Adding transactional method [save] with attribute 
[PROPAGATION_REQUIRED,ISOLATION_DEFAULT]

** Note this entry **
DEBUG JpaTransactionManager - Found thread-bound EntityManager
[org.hibernate.ejb.EntityManagerImpl@13e6f83] for JPA transaction

DEBUG JpaTransactionManager - Creating new transaction with name 
[com.mycorp.service.ContactService.save]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
DEBUG DriverManagerDataSource - Creating new JDBC DriverManager Connection to [jdbc:hsqldb:mem:demoDB]
DEBUG JpaTransactionManager - Exposing JPA transaction as JDBC transaction [SimpleConnectionHandle: 
org.hsqldb.jdbc.jdbcConnection@b0c5a]
Hibernate: insert into Contact (id, firstname, lastname, email) values (null, ?, ?, ?)
Hibernate: call identity()
DEBUG JpaTransactionManager - Initiating transaction commit
DEBUG JpaTransactionManager - Committing JPA transaction on EntityManager 
[org.hibernate.ejb.EntityManagerImpl@13e6f83]

** NOTE this entry **
DEBUG JpaTransactionManager - Not closing pre-bound JPA EntityManager after transaction

...

DEBUG OpenEntityManagerInViewFilter - Closing JPA EntityManager in OpenEntityManagerInViewFilter
DEBUG EntityManagerFactoryUtils - Closing JPA EntityManager



Bob Schellink wrote:
 > Hi Doychi,
 >
 > Your transaction setting looks right. Have a look at your logs at
 > startup for anything odd. Check that only one EntityManagerFactory or
 > SessionFactory is created. Other than that I'm out of ideas at this
 > point. Play around with the @Transactional annotation (remove it and see
 > what happens). It seems to me like a Spring config issue so you might
 > want to post on their forum for some help on this.
 >
 > Let us know how it goes.
 >
 > kind regards
 >
 > bob
 >
 >
 > Doychi wrote:
 >> Hi Bob,
 >>
 >> I'm using org.springframework.orm.jpa.JpaTransactionManager with
 >> <tx:annotation-driven /> for transactions.
 >>
 >>
 >> Bob Schellink-2 wrote:
 >>> Been doing some investigation myself and seems that @Transactional
 >>> might in fact work with the OpenEntityManagerInView filter.
 >>>
 >>> @Doychi: Which transaction manager have you defined in your spring.xml?
 >>>
 >>>
 >>
 >> --
 >> Doychi
 >
 >


Re: Click 2, Spring and JPA Lazy Initialisation Error

Posted by Bob Schellink <sa...@gmail.com>.
Hi Doychi,

Your transaction setting looks right. Have a look at your logs at 
startup for anything odd. Check that only one EntityManagerFactory or 
SessionFactory is created. Other than that I'm out of ideas at this 
point. Play around with the @Transactional annotation (remove it and see 
what happens). It seems to me like a Spring config issue so you might 
want to post on their forum for some help on this.

Let us know how it goes.

kind regards

bob


Doychi wrote:
> Hi Bob,
> 
> I'm using org.springframework.orm.jpa.JpaTransactionManager with
> <tx:annotation-driven /> for transactions.
> 
> 
> Bob Schellink-2 wrote:
>> Been doing some investigation myself and seems that @Transactional might 
>> in fact work with the OpenEntityManagerInView filter.
>>
>> @Doychi: Which transaction manager have you defined in your spring.xml?
>>
>>
> 
> --
> Doychi


Re: Click 2, Spring and JPA Lazy Initialisation Error

Posted by Doychi <do...@doychi-dina.ath.cx>.
Hi Bob,

I'm using org.springframework.orm.jpa.JpaTransactionManager with
<tx:annotation-driven /> for transactions.


Bob Schellink-2 wrote:
> 
> Been doing some investigation myself and seems that @Transactional might 
> in fact work with the OpenEntityManagerInView filter.
> 
> @Doychi: Which transaction manager have you defined in your spring.xml?
> 
> 

--
Doychi
-- 
View this message in context: http://n2.nabble.com/Click-2-Spring-and-JPA-Lazy-Initialisation-Error-tp3857539p3871655.html
Sent from the click-user mailing list archive at Nabble.com.

Re: Click 2, Spring and JPA Lazy Initialisation Error

Posted by Bob Schellink <sa...@gmail.com>.
Been doing some investigation myself and seems that @Transactional might 
in fact work with the OpenEntityManagerInView filter.

@Doychi: Which transaction manager have you defined in your spring.xml?


Bob Schellink wrote:
> 
>>
>> Bob, you are right about the EnityManger being closed.  I spent quite 
>> a bit
>> of time looking into the error and the Spring forums say that the 
>> listener
>> (org.springframework.web.context.ContextLoaderListener) should work in 
>> the
>> same way.  Either way, I get the same error whether I use the listener or
>> the open view filter.  
> 
> 
> The ContextLoaderListener is Spring's bootstrap mechanism in web 
> applications. In other words when the web application starts up, 
> ContextLoaderListener will read your spring.xml file and create the 
> Spring ApplicationContext. It won't open or close the EntityManager or 
> commit transactions. So I'm fairly confident that ContextLoaderListener 
> is not where the issue lies.
> 
> I still think the problem lies in the fact that you have the 
> @Transactional annotation on your Repository. Btw I'm not saying that 
> having @Transaction on the Repository is wrong, its just that it means 
> the Transaction will commit whenever a method on Repository is invoked, 
> and the session will get closed. If you want to use @Transactional on 
> your Repository you basically need to know which entities to load eagerly.
> 
> I suggest you try the following and see what happens: declare the 
> OpenEntityManagerInViewFilter in your web.xml. This filter binds an 
> EntityManager instance to the thread for the duration of the request. 
> However even if you have the filter, the @Transactional annotation will 
> still commit the transaction (and close the session) after any 
> Repository method is invoked. So try and remove the @Transactional 
> annotation from the Repository and see what happens. Do you still get 
> the lazy exception? Very likely something else will break but at least 
> this should prove the theory of @Transactional :)
> 
> Let us know your findings.
> 
> kind regards
> 
> bob
> 
> 
>>
>> BTW thanks for any assistance.
>>
>> [Click] [error] handleException: 
>> org.hibernate.LazyInitializationException:
>> failed to lazily initialize a collection of role:
>> au.org.pheno.f1.domain.attendees.jpa.PrincipalJpa.registeredForEvents, no
>> session or session was closed
>>     at
>> org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358) 
>>
>>     at
>> org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350) 
>>
>>     at
>> org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343) 
>>
>>     at
>> org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86) 
>>
>>     at 
>> org.hibernate.collection.PersistentBag.toString(PersistentBag.java:483)
>>     at java.lang.String.valueOf(String.java:2838)
>>     at java.lang.StringBuffer.append(StringBuffer.java:236)
>>     at
>> org.apache.commons.lang.builder.ToStringStyle.appendDetail(ToStringStyle.java:590) 
>>
>>     at
>> org.apache.commons.lang.builder.ToStringStyle.appendInternal(ToStringStyle.java:465) 
>>
>>     at
>> org.apache.commons.lang.builder.ToStringStyle.append(ToStringStyle.java:428) 
>>
>>     at
>> org.apache.commons.lang.builder.ToStringBuilder.append(ToStringBuilder.java:840) 
>>
>>     at
>> org.apache.commons.lang.builder.ReflectionToStringBuilder.appendFieldsIn(ReflectionToStringBuilder.java:606) 
>>
>>     at
>> org.apache.commons.lang.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:759) 
>>
>>     at
>> org.apache.commons.lang.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:287) 
>>
>>     at
>> org.apache.commons.lang.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:121) 
>>
>>     at
>> org.apache.commons.lang.builder.ToStringBuilder.reflectionToString(ToStringBuilder.java:126) 
>>
>>     at
>> au.org.pheno.f1.domain.attendees.jpa.PrincipalJpa.toString(PrincipalJpa.java:655) 
>>
>>     at au.org.pheno.f1.test.pages.LoginPage.onInit(LoginPage.java:66)
>>     at org.apache.click.ClickServlet.processPage(ClickServlet.java:512)
>>     at org.apache.click.ClickServlet.handleRequest(ClickServlet.java:334)
>>     at org.apache.click.ClickServlet.doGet(ClickServlet.java:253)
>>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
>>     at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
>>     at
>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) 
>>
>>     at
>> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
>>
>>     at
>> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) 
>>
>>     at
>> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
>>
>>     at
>> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) 
>>
>>     at
>> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) 
>>
>>     at
>> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 
>>
>>     at
>> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) 
>>
>>     at
>> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849) 
>>
>>     at
>> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) 
>>
>>     at 
>> org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
>>     at java.lang.Thread.run(Thread.java:636)
> 
> 


Re: Click 2, Spring and JPA Lazy Initialisation Error

Posted by Bob Schellink <sa...@gmail.com>.
> 
> Bob, you are right about the EnityManger being closed.  I spent quite a bit
> of time looking into the error and the Spring forums say that the listener
> (org.springframework.web.context.ContextLoaderListener) should work in the
> same way.  Either way, I get the same error whether I use the listener or
> the open view filter.  


The ContextLoaderListener is Spring's bootstrap mechanism in web 
applications. In other words when the web application starts up, 
ContextLoaderListener will read your spring.xml file and create the 
Spring ApplicationContext. It won't open or close the EntityManager or 
commit transactions. So I'm fairly confident that ContextLoaderListener 
is not where the issue lies.

I still think the problem lies in the fact that you have the 
@Transactional annotation on your Repository. Btw I'm not saying that 
having @Transaction on the Repository is wrong, its just that it means 
the Transaction will commit whenever a method on Repository is invoked, 
and the session will get closed. If you want to use @Transactional on 
your Repository you basically need to know which entities to load eagerly.

I suggest you try the following and see what happens: declare the 
OpenEntityManagerInViewFilter in your web.xml. This filter binds an 
EntityManager instance to the thread for the duration of the request. 
However even if you have the filter, the @Transactional annotation will 
still commit the transaction (and close the session) after any 
Repository method is invoked. So try and remove the @Transactional 
annotation from the Repository and see what happens. Do you still get 
the lazy exception? Very likely something else will break but at least 
this should prove the theory of @Transactional :)

Let us know your findings.

kind regards

bob


> 
> BTW thanks for any assistance.
> 
> [Click] [error] handleException: org.hibernate.LazyInitializationException:
> failed to lazily initialize a collection of role:
> au.org.pheno.f1.domain.attendees.jpa.PrincipalJpa.registeredForEvents, no
> session or session was closed
> 	at
> org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
> 	at
> org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
> 	at
> org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
> 	at
> org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
> 	at org.hibernate.collection.PersistentBag.toString(PersistentBag.java:483)
> 	at java.lang.String.valueOf(String.java:2838)
> 	at java.lang.StringBuffer.append(StringBuffer.java:236)
> 	at
> org.apache.commons.lang.builder.ToStringStyle.appendDetail(ToStringStyle.java:590)
> 	at
> org.apache.commons.lang.builder.ToStringStyle.appendInternal(ToStringStyle.java:465)
> 	at
> org.apache.commons.lang.builder.ToStringStyle.append(ToStringStyle.java:428)
> 	at
> org.apache.commons.lang.builder.ToStringBuilder.append(ToStringBuilder.java:840)
> 	at
> org.apache.commons.lang.builder.ReflectionToStringBuilder.appendFieldsIn(ReflectionToStringBuilder.java:606)
> 	at
> org.apache.commons.lang.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:759)
> 	at
> org.apache.commons.lang.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:287)
> 	at
> org.apache.commons.lang.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:121)
> 	at
> org.apache.commons.lang.builder.ToStringBuilder.reflectionToString(ToStringBuilder.java:126)
> 	at
> au.org.pheno.f1.domain.attendees.jpa.PrincipalJpa.toString(PrincipalJpa.java:655)
> 	at au.org.pheno.f1.test.pages.LoginPage.onInit(LoginPage.java:66)
> 	at org.apache.click.ClickServlet.processPage(ClickServlet.java:512)
> 	at org.apache.click.ClickServlet.handleRequest(ClickServlet.java:334)
> 	at org.apache.click.ClickServlet.doGet(ClickServlet.java:253)
> 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
> 	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
> 	at
> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
> 	at
> org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
> 	at
> org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
> 	at
> org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
> 	at
> org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
> 	at
> org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
> 	at
> org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
> 	at
> org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
> 	at
> org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
> 	at
> org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
> 	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
> 	at java.lang.Thread.run(Thread.java:636)


Re: Click 2, Spring and JPA Lazy Initialisation Error

Posted by Doychi <do...@doychi-dina.ath.cx>.
Hi Malcolm & Bob,

Your right, it probably will help (see below). 

It appears that it's the logger that's causing the problem.  I just took the
logging statement out and it worked.  Any suggestions on how to get the
logger to work with?

Bob, you are right about the EnityManger being closed.  I spent quite a bit
of time looking into the error and the Spring forums say that the listener
(org.springframework.web.context.ContextLoaderListener) should work in the
same way.  Either way, I get the same error whether I use the listener or
the open view filter.  

BTW thanks for any assistance.

[Click] [error] handleException: org.hibernate.LazyInitializationException:
failed to lazily initialize a collection of role:
au.org.pheno.f1.domain.attendees.jpa.PrincipalJpa.registeredForEvents, no
session or session was closed
	at
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358)
	at
org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350)
	at
org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343)
	at
org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
	at org.hibernate.collection.PersistentBag.toString(PersistentBag.java:483)
	at java.lang.String.valueOf(String.java:2838)
	at java.lang.StringBuffer.append(StringBuffer.java:236)
	at
org.apache.commons.lang.builder.ToStringStyle.appendDetail(ToStringStyle.java:590)
	at
org.apache.commons.lang.builder.ToStringStyle.appendInternal(ToStringStyle.java:465)
	at
org.apache.commons.lang.builder.ToStringStyle.append(ToStringStyle.java:428)
	at
org.apache.commons.lang.builder.ToStringBuilder.append(ToStringBuilder.java:840)
	at
org.apache.commons.lang.builder.ReflectionToStringBuilder.appendFieldsIn(ReflectionToStringBuilder.java:606)
	at
org.apache.commons.lang.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:759)
	at
org.apache.commons.lang.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:287)
	at
org.apache.commons.lang.builder.ReflectionToStringBuilder.toString(ReflectionToStringBuilder.java:121)
	at
org.apache.commons.lang.builder.ToStringBuilder.reflectionToString(ToStringBuilder.java:126)
	at
au.org.pheno.f1.domain.attendees.jpa.PrincipalJpa.toString(PrincipalJpa.java:655)
	at au.org.pheno.f1.test.pages.LoginPage.onInit(LoginPage.java:66)
	at org.apache.click.ClickServlet.processPage(ClickServlet.java:512)
	at org.apache.click.ClickServlet.handleRequest(ClickServlet.java:334)
	at org.apache.click.ClickServlet.doGet(ClickServlet.java:253)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	at
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
	at
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
	at java.lang.Thread.run(Thread.java:636)
-- 
View this message in context: http://n2.nabble.com/Click-2-Spring-and-JPA-Lazy-Initialisation-Error-tp3857539p3871243.html
Sent from the click-user mailing list archive at Nabble.com.

Re: Click 2, Spring and JPA Lazy Initialisation Error

Posted by Bob Schellink <sa...@gmail.com>.
Hi Doychi,

I've never used JPA before but have a little Hibernate experience. Now 
sure if you're using JPA through Hibernate or a different implementation?

Anyway the error you receive indicates that the session (EntityManager?) 
was closed (somewhere in the lower layer of your app) by the time the 
view needs to iterate over the roles.

My Spring/Hibernate is a little rusty but I think the following is 
happening. Your Repository contains the annotation @Transactional. Its a 
Spring construct which means (as I recall) that invoking any method on 
the Repository will create a new transaction before the method starts 
and commit the transaction before the method returns. Depending on how 
you configured your spring.xml, it might mean the session 
(EntityManager?) is closed when the transaction is committed.

How do you configure spring to create transactions and the 
EntityManager? Can you post it here?

You might want to look at the OpenEntityManagerInViewFilter which opens 
an EntityManager when the request arrives, and keeps it open until the 
request finishes. Thus the EntityManager will be open in your view and 
the lazy initialization won't occur. Alternatively you need to eagerly 
load the role.

Hope this helps.

bob


Doychi wrote:
> Hi all,
> 
> I'm hoping someone can help me with a lazy initialisation error.  The error
> I am getting is:
> 
>     failed to lazily initialize a collection of role ... no session or
> session was closed
> 
> I am using Click 2's SpringClickServlet configured in the web.xml and JPA.
> 
> This is my web.xml, which seems to load everything okay.
> 
> 
> <web-app>
> 	<listener>
> 	
> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
> 	</listener>
> 	<servlet>
> 		<servlet-name>SpringClickServlet</servlet-name>
> 		<servlet-class>au.org.pheno.f1.click.SpringClickServlet</servlet-class>
> 		<load-on-startup>0</load-on-startup>
> 	</servlet>
> 	<servlet-mapping>
> 		<servlet-name>SpringClickServlet</servlet-name>
> 		<url-pattern>*.htm</url-pattern>
> 	</servlet-mapping>
> </web-app>
> 
> 
> The page, which was taken from my login page, is trying to load a user
> (principal) and display its roles to test the lazy loading issue.
> 
> 
> /*
>  * To change this template, choose Tools | Templates
>  * and open the template in the editor.
>  */
> package au.org.pheno.f1.test.pages;
> 
> import javax.annotation.Resource;
> 
> import org.apache.click.Page;
> import org.apache.log4j.Logger;
> import org.springframework.stereotype.Component;
> 
> import au.org.pheno.f1.domain.attendees.Principal;
> import au.org.pheno.f1.repository.attendees.IPrincipalRepository;
> 
> /**
>  * The login screen provides a user a way to login to the system.
>  * 
>  * @author doychi
>  */
> @Component("au.org.pheno.f1.test.pages.LoginPage")
> public class LoginPage extends Page {
> 
>     private static final String TITLE = "Test Page";
>     public String msg = "";
>     private IPrincipalRepository repository;
>     private Logger log = Logger.getLogger(LoginPage.class);
>     public Principal principal;
> 
>     private Logger getLogger() {
> 	return log;
>     }
> 
>     /**
>      * Retrieve the title
>      * 
>      * @return the title
>      */
>     public String getTitle() {
> 	return TITLE;
>     }
> 
>     /**
>      * Set the principal repository to use for the page.
>      * 
>      * @param principalRepository
>      *            the repository to use
>      */
>     @Resource(name = "principalRepository")
>     public void setPrincipalRepository(IPrincipalRepository
> principalRepository) {
> 	if (getLogger().isDebugEnabled()) {
> 	    getLogger().debug("IPrincipalRepository set");
> 	}
> 
> 	this.repository = principalRepository;
>     }
> 
>     public IPrincipalRepository getPrincipalRepository() {
> 	return repository;
>     }
> 
>     @Override
>     public void onInit() {
> 	super.onInit();
> 	principal = repository.principalByLogin("admin");
> 	getLogger().info(principal.toString());
>     }
> 
> }
> 
> 
> The principal repository looks like this:
> 
> 
> package au.org.pheno.f1.repository.attendees.jpa;
> 
> import java.util.ArrayList;
> import java.util.List;
> import java.util.Map;
> import java.util.Set;
> import java.util.TreeMap;
> 
> import org.apache.commons.lang.StringUtils;
> import org.apache.commons.lang.builder.ReflectionToStringBuilder;
> import org.apache.log4j.Logger;
> import org.springframework.dao.DataAccessException;
> import org.springframework.security.AuthenticationServiceException;
> import org.springframework.security.BadCredentialsException;
> import org.springframework.security.userdetails.UserDetails;
> import org.springframework.security.userdetails.UsernameNotFoundException;
> import org.springframework.stereotype.Component;
> import org.springframework.transaction.annotation.Transactional;
> 
> import au.org.pheno.f1.domain.attendees.Principal;
> import au.org.pheno.f1.domain.attendees.Role;
> import au.org.pheno.f1.repository.Repository;
> import au.org.pheno.f1.repository.WrongNumberOfResultsReturnedException;
> import au.org.pheno.f1.repository.attendees.IPrincipalRepository;
> 
> /**
>  * Class description
>  * 
>  * 
>  * @version Enter version here..., 07/12/26
>  * @author Enter your name here...
>  */
> @Component("principalRepository")
> @Transactional(readOnly = true)
> public class PrincipalRepository extends Repository<Principal> implements
> 	IPrincipalRepository {
> 
>     private String LOGIN_TAG = "usr";
>     private static final Logger log = Logger
> 	    .getLogger(PrincipalRepository.class);
>     private static final String FILTER_OP_BOOLEAN = " = ";
>     private static final String FILTER_OP_INTEGER = " = ";
>     private static final String FILTER_OP_STRING = " LIKE ";
> .
> .
> .
>     /**
>      * {@inheritdoc}
>      */
>     @Override
>     public Principal principalByLogin(String login) {
> 	Principal result;
> 	String query = "SELECT principal FROM PrincipalJpa principal WHERE "
> 		+ "principal.username = :" + LOGIN_TAG;
> 	Map<String, Object> params = new TreeMap<String, Object>();
> 
> 	params.put(LOGIN_TAG, login);
> 
> 	result = (Principal) readOne(query, params);
> 
> 	return result;
>     }
> .
> .
> .
> }
> 
> 
> The error appears to be thrown when my template tries to list the roles:
> 
> 
> <html>
> <body>
> <p class="errorMessage">
>     $!msg
> </p>
> ${principal.firstName} ${principal.lastName}
> #foreach( $role in $principal.roles)
> 	$role.name
> #end
> </body>
> </html>
> 
> 
> Does anyone have any thoughts on what I'm doing wrong?
> 
> Thanks,
> --
> Doychi


Re: Click 2, Spring and JPA Lazy Initialisation Error

Posted by Malcolm Edgar <ma...@gmail.com>.
HI Doychi,
I would recommend that you provide the full stack trace as it will be more
informative than the summary line.

regards Malcolm Edgar

On Tue, Oct 20, 2009 at 8:12 PM, Doychi <do...@doychi-dina.ath.cx>wrote:

>
> Hi all,
>
> I'm hoping someone can help me with a lazy initialisation error.  The error
> I am getting is:
>
>    failed to lazily initialize a collection of role ... no session or
> session was closed
>
> I am using Click 2's SpringClickServlet configured in the web.xml and JPA.
>
> This is my web.xml, which seems to load everything okay.
>
>
> <web-app>
>        <listener>
>
>
> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
>        </listener>
>        <servlet>
>                <servlet-name>SpringClickServlet</servlet-name>
>
>  <servlet-class>au.org.pheno.f1.click.SpringClickServlet</servlet-class>
>                <load-on-startup>0</load-on-startup>
>        </servlet>
>        <servlet-mapping>
>                <servlet-name>SpringClickServlet</servlet-name>
>                <url-pattern>*.htm</url-pattern>
>        </servlet-mapping>
> </web-app>
>
>
> The page, which was taken from my login page, is trying to load a user
> (principal) and display its roles to test the lazy loading issue.
>
>
> /*
>  * To change this template, choose Tools | Templates
>  * and open the template in the editor.
>  */
> package au.org.pheno.f1.test.pages;
>
> import javax.annotation.Resource;
>
> import org.apache.click.Page;
> import org.apache.log4j.Logger;
> import org.springframework.stereotype.Component;
>
> import au.org.pheno.f1.domain.attendees.Principal;
> import au.org.pheno.f1.repository.attendees.IPrincipalRepository;
>
> /**
>  * The login screen provides a user a way to login to the system.
>  *
>  * @author doychi
>  */
> @Component("au.org.pheno.f1.test.pages.LoginPage")
> public class LoginPage extends Page {
>
>    private static final String TITLE = "Test Page";
>    public String msg = "";
>    private IPrincipalRepository repository;
>    private Logger log = Logger.getLogger(LoginPage.class);
>    public Principal principal;
>
>    private Logger getLogger() {
>        return log;
>    }
>
>    /**
>     * Retrieve the title
>     *
>     * @return the title
>     */
>    public String getTitle() {
>        return TITLE;
>    }
>
>    /**
>     * Set the principal repository to use for the page.
>     *
>     * @param principalRepository
>     *            the repository to use
>     */
>    @Resource(name = "principalRepository")
>    public void setPrincipalRepository(IPrincipalRepository
> principalRepository) {
>        if (getLogger().isDebugEnabled()) {
>            getLogger().debug("IPrincipalRepository set");
>        }
>
>        this.repository = principalRepository;
>    }
>
>    public IPrincipalRepository getPrincipalRepository() {
>        return repository;
>    }
>
>    @Override
>    public void onInit() {
>        super.onInit();
>        principal = repository.principalByLogin("admin");
>        getLogger().info(principal.toString());
>    }
>
> }
>
>
> The principal repository looks like this:
>
>
> package au.org.pheno.f1.repository.attendees.jpa;
>
> import java.util.ArrayList;
> import java.util.List;
> import java.util.Map;
> import java.util.Set;
> import java.util.TreeMap;
>
> import org.apache.commons.lang.StringUtils;
> import org.apache.commons.lang.builder.ReflectionToStringBuilder;
> import org.apache.log4j.Logger;
> import org.springframework.dao.DataAccessException;
> import org.springframework.security.AuthenticationServiceException;
> import org.springframework.security.BadCredentialsException;
> import org.springframework.security.userdetails.UserDetails;
> import org.springframework.security.userdetails.UsernameNotFoundException;
> import org.springframework.stereotype.Component;
> import org.springframework.transaction.annotation.Transactional;
>
> import au.org.pheno.f1.domain.attendees.Principal;
> import au.org.pheno.f1.domain.attendees.Role;
> import au.org.pheno.f1.repository.Repository;
> import au.org.pheno.f1.repository.WrongNumberOfResultsReturnedException;
> import au.org.pheno.f1.repository.attendees.IPrincipalRepository;
>
> /**
>  * Class description
>  *
>  *
>  * @version Enter version here..., 07/12/26
>  * @author Enter your name here...
>  */
> @Component("principalRepository")
> @Transactional(readOnly = true)
> public class PrincipalRepository extends Repository<Principal> implements
>        IPrincipalRepository {
>
>    private String LOGIN_TAG = "usr";
>    private static final Logger log = Logger
>            .getLogger(PrincipalRepository.class);
>    private static final String FILTER_OP_BOOLEAN = " = ";
>    private static final String FILTER_OP_INTEGER = " = ";
>    private static final String FILTER_OP_STRING = " LIKE ";
> .
> .
> .
>    /**
>     * {@inheritdoc}
>     */
>    @Override
>    public Principal principalByLogin(String login) {
>        Principal result;
>        String query = "SELECT principal FROM PrincipalJpa principal WHERE "
>                + "principal.username = :" + LOGIN_TAG;
>        Map<String, Object> params = new TreeMap<String, Object>();
>
>        params.put(LOGIN_TAG, login);
>
>        result = (Principal) readOne(query, params);
>
>        return result;
>    }
> .
> .
> .
> }
>
>
> The error appears to be thrown when my template tries to list the roles:
>
>
> <html>
> <body>
> <p class="errorMessage">
>    $!msg
> </p>
> ${principal.firstName} ${principal.lastName}
> #foreach( $role in $principal.roles)
>        $role.name
> #end
> </body>
> </html>
>
>
> Does anyone have any thoughts on what I'm doing wrong?
>
> Thanks,
> --
> Doychi
> --
> View this message in context:
> http://n2.nabble.com/Click-2-Spring-and-JPA-Lazy-Initialisation-Error-tp3857539p3857539.html
> Sent from the click-user mailing list archive at Nabble.com.
>