0

Again LazyInitializationException with ZK+Spring+Hibernate

asked 2009-08-28 08:15:51 +0800

tomCat gravatar image tomCat
276 3

updated 2009-08-28 08:17:16 +0800

Hi i receive the following exception when i try to display the keywords
of my Address Object:

28.08.2009 09:57:24:  (LazyInitializationException.java:42) <init>: failed to lazily initialize a collection of role: model.Address.keywords, no session or session was closed ...

Spring closes the Session after I retrieved the Address from the Database. Perhaps i am totally wrong, but i thought Spring should keep the Session alive trough the @Transactional
Annotation inside my GenericServiceImpl.
My questions:

- What am i doing wrong?
- How can i "lazy load" the keywords of my Address Object?

Best regards,
tomCat

My Code:

index.zul:

<?page title="Auto Generated index.zul"?>
<?variable-resolver class="org.zkoss.zkplus.spring.DelegatingVariableResolver"?>
<window title="Hello World!!" border="normal" width="100%" apply="${addressController}">

	<textbox id="textbox" />
	<listbox id="listbox" />
	<button id="btn_search" label="Suche" />
	<button id="btn_displayKewords" label="Zeige Stichworte" />
	

</window>

web.xml:

<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">
	...
	<!-- Spring Configuration -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/conf/spring/spring-config.xml</param-value>
	</context-param>
	
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
    <!-- END SPRING -->
     ...
			
</web-app>

zk.xml:

<zk>
	<listener>
    	<description>Spring TransactionSynchronizationManager handler</description>
    	<listener-class>org.zkoss.zkplus.spring.SpringTransactionSynchronizationListener</listener-class>
	</listener>

	<listener>
		<description>ThreadLocal Synchronization Listener
		</description>
		<listener-class>org.zkoss.zkplus.util.ThreadLocalListener
		</listener-class>
	</listener>

	<preference>
		<name>ThreadLocal</name>
                 <value>org.springframework.transaction.support.TransactionSynchronizationManager=resources,
                        synchronizations,currentTransactionName,currentTransactionReadOnly,actualTransactionActive;
			org.springframework.orm.hibernate3.SessionFactoryUtils=deferredCloseHolder;
			org.springframework.transaction.interceptor.TransactionAspectSupport=transactionInfoHolder;
		</value>
	</preference>	
</zk>

AddressController.java:

public class AddressController extends GenericForwardComposer {

	// Fields
	protected Textbox textbox; //autowired
	protected Listbox listbox; //autowired
	// Service Object
	private GenericService<Address, BigDecimal> service;
	// Domain Object
	private Address address;	
	
	public AddressController(GenericService<Address, BigDecimal> service) {
		this.service = service;
	}
	
	public void onClick$btn_search() {
		address = service.get(new BigDecimal(40043));
		textbox.setValue(address.getSearchname());
	}
	
	public void onClick$btn_displayKewords() {
		System.out.println("Display Keywords");
		listbox.setModel(new SimpleListModel(address.getKeywords()));
	}
}

GenericServiceImpl.java:

@Transactional
public class GenericServiceImpl<T, PK extends Serializable> implements GenericService<T, PK> {

	private GenericDao<T, PK> genericDao;
	
	public GenericServiceImpl(GenericDao<T, PK> genericDao) {
		this.genericDao = genericDao;
	}
	
	@Override
	public T get(PK id) throws DataAccessException {
		// TODO Auto-generated method stub
		return genericDao.get(id);
	}
	
}

spring-config.xml

<beans...>
	<!-- Hibernate configuration -->
	<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location">
			<value>/WEB-INF/conf/hibernate.properties</value>
		</property>
	</bean>
	
	<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
               ...
	</bean>
	
	<!-- Hibernate SessionFactory mit Annotationen -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource"><ref bean="dataSource"/></property>
		<property name="hibernateProperties">
			<props>
                                ...
			</props>
		</property>
		<property name="annotatedClasses">
			<list>				
				<value>model.Address</value>
				<value>model.Keyword</value>			
			</list>
		</property>
		<property name="eventListeners">
			<map>
				<entry key="merge">
					<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
				</entry>
			</map>
		</property>
		
	</bean>
	
	<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory"><ref local="sessionFactory"/></property>
	</bean>
	
	<bean id="addressController" class="controller.AddressController">
		<constructor-arg ref="addressService" />
	</bean>
	
	<bean id="addressDao" class="dao.impl.GenericDaoImpl">
		<constructor-arg index="0" value="model.Address" />
		<constructor-arg ref="sessionFactory" />
	</bean>
	
	<bean id="addressService" class="service.impl.GenericServiceImpl">
		<constructor-arg ref="addressDao" />
	</bean>
	
	<tx:annotation-driven transaction-manager="transactionManager" />
</beans>

Address.java:

package model;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="bp_adressen")
public class Address implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 8760158446166372476L;
	@Id
	@Column(name="bp_adressenid")
	private BigDecimal id;
	@Column(name="suchname")
	private String searchname;
	@OneToMany(cascade=CascadeType.ALL)
	@JoinColumn(name="bp_adressenid")
	List<Keyword> keywords;
	
	...
}

delete flag offensive retag edit
Be the first one to reply this discussion!
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2009-08-28 08:15:51 +0800

Seen: 656 times

Last updated: Aug 28 '09

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More