Announcement Announcement Module
Collapse
No announcement yet.
Lazy Loading Exception,Please give a hand Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Lazy Loading Exception,Please give a hand

    I used the Spring2.0M3 and Hibernate EntityManager3.1.6 beta
    Here is my configuration:
    persistence.xml,(NO hibernate.cfg.xml)
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence>
       <persistence-unit name="ebEntityManager" transaction-type="RESOURCE_LOCAL">
          <provider>org.hibernate.ejb.HibernatePersistence</provider>
          <class>com.jl.eb.dao.Category</class>
          <class>com.jl.eb.dao.CategoryItem</class>
          <properties>
              <property name="hibernate.dialect" value="org.hibernate.dialect.DB2Dialect" />
              <property name="hibernate.connection.driver_class" value="com.ibm.db2.jcc.DB2Driver" />
              <property name="hibernate.connection.password" value="db2admin" />
              <property name="hibernate.connection.url" value="jdbc:db2://10.1.1.10:50000/dbjl" />
              <property name="hibernate.connection.username" value="db2admin" />
              <property name="hibernate.ejb.autodetection" value="class" />
              <property name="hibernate.max_fetch_depth" value="3"/>          
    	 </properties>
       </persistence-unit>
    </persistence>
    And then my mapping file:
    Code:
    package com.jl.eb.dao;
    import java.math.*;
    import java.util.*;
    import javax.persistence.*;
    import java.text.*;
    
    @Entity
    @Table(name = "category", schema = "eb", uniqueConstraints = {})
    public class Category implements java.io.Serializable {
    	private String id; 
    	private String compId; 
    	private String name; 
    	private String no; 
    	private Integer level;
    	private String desc; 
    	private String parentId;
    	private String sysEmp;
    	private Date sysDate; 
    	private Set<CategoryItem> categoryItem = new HashSet<CategoryItem>(); 
    	@Id
    	@Column(name = "id", length = 32)
    	public String getId() {	return this.id;	}
    	public void setId(String id) {	this.id = id;}
    	@Column(name = "comp_Id", length = 20)
    	public String getCompId() {return this.compId;}
    	public void setCompId(String compId) {this.compId = compId;}
    	@Column(name = "name", length = 60)
    	public String getName() {return this.name;}
    	public void setName(String name) {this.name = name;}
    	@Column(name = "no", length = 13)
    	public String getNo() {return this.no;}
    	public void setNo(String no) {this.no = no;}
    	@Column(name = "level")
    	public Integer getLevel() {return this.level;}
    	public void setLevel(Integer level) {this.level = level;}
    	public void setLevel(String value) {this.level = Integer.parseInt(value);}
    
    	@Column(name = "desc", length = 60)
    	public String getDesc() {return this.desc;}
    	public void setDesc(String desc) {this.desc = desc;}
    	@Column(name = "parent_id", length = 32)
    	public String getParentId() {return this.parentId;}
    	public void setParentId(String parentId) {this.parentId = parentId;}
    	@Column(name = "sys_emp", length = 20)
    	public String getSysEmp() {return this.sysEmp;}
    	public void setSysEmp(String sysEmp) {this.sysEmp = sysEmp;}
    	@Column(name = "sys_date", length = 10)
    	public Date getSysDate() {return this.sysDate;}
    	public void setSysDate(Date sysDate) {this.sysDate = sysDate;}
    	public void setSysDate(String value) throws ParseException {
    		value = value.replace("-", "");
    		value = value.replace("/", "");
    		this.sysDate = new SimpleDateFormat("yyyyMMdd").parse(value);
    	}
    
    	@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, mappedBy = "category")
    	public Set<CategoryItem> getCategoryItem() {return this.categoryItem;}
    	public void setCategoryItem(Set<CategoryItem> categoryItem) {this.categoryItem = categoryItem;}
    
    }
    package com.jl.eb.dao;
    import java.math.*;
    import java.util.*;
    import javax.persistence.*;
    import java.text.*;
    
    @Entity
    @Table(name = "category_item", schema = "eb", uniqueConstraints = {})
    public class CategoryItem implements java.io.Serializable {
    	private String id; 
    	private String no; 
    	private String desc; 
    	private String sysEmp; 
    	private Date sysDate; 
    	private Category category; 
    
    	@Id
    	@Column(name = "id", length = 32)
    	public String getId() {	return this.id;	}
    	public void setId(String id) {this.id = id;}
    	@Column(name = "no", length = 3)
    	public String getNo() {	return this.no;}
    	public void setNo(String no) {this.no = no;}
    	@Column(name = "desc", length = 100)
    	public String getDesc() {return this.desc;}
    	public void setDesc(String desc) {this.desc = desc;}
    	@Column(name = "sys_emp", length = 20)
    	public String getSysEmp() {return this.sysEmp;}
    	public void setSysEmp(String sysEmp) {this.sysEmp = sysEmp;}
    	@Column(name = "sys_date", length = 10)
    	public Date getSysDate() {return this.sysDate;}
    	public void setSysDate(Date sysDate) {this.sysDate = sysDate;}
    	public void setSysDate(String value) throws ParseException {
    		value = value.replace("-", "");
    		value = value.replace("/", "");
    		this.sysDate = new SimpleDateFormat("yyyyMMdd").parse(value);
    	}
    
    	@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
    	@JoinColumn(name = "category_id", unique = false, nullable = true, insertable = true, updatable = true)
    	public Category getCategory() {	return this.category;}
    	public void setCategory(Category category) {this.category = category;}
    
    }
    and then,I have two spring config file
    spring_dao.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation=
                 "http://www.springframework.org/schema/beans 
                  http://www.springframework.org/schema/beans/spring-beans.xsd
                  http://www.springframework.org/schema/aop 
                  http://www.springframework.org/schema/aop/spring-aop.xsd">
    	<bean id="ebEntityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    		<property name="entityManagerName" value="ebEntityManager"/>
    		<property name="jpaProperties"><props></props></property>
    	</bean>
    	
    	<bean id="ebTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    		<property name="entityManagerFactory" ref="ebEntityManagerFactory" />
    	</bean>
    	
    	<bean id="ebTransactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
    		<property name="transactionManager" ref="ebTransactionManager" />
    		<property name="transactionAttributeSource">
    			<bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" />
    		</property>
    	</bean>
    	
    	<bean id="ebTransactionAttributeSourceAdvisor"
    		class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
    		<property name="transactionInterceptor" ref="ebTransactionInterceptor"/>
    	</bean>
    	
    	<bean id="ebOpenEMinView" class="org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor">
    		<property name="entityManagerFactory" ref="ebEntityManagerFactory"/>
    	</bean>
    	<!-- DAO start -->
    	<bean id="eb_CategoryDAO" class="com.jl.eb.dao.CategoryDAO">
    		<property name="entityManagerFactory" ref="ebEntityManagerFactory" />
    	</bean>
    	
    	<bean id="eb_CategoryItemDAO" class="com.jl.eb.dao.CategoryItemDAO">
    		<property name="entityManagerFactory" ref="ebEntityManagerFactory" />
    	</bean>
    		
    </beans>
    spring_logic.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation=
                 "http://www.springframework.org/schema/beans 
                  http://www.springframework.org/schema/beans/spring-beans.xsd
                  http://www.springframework.org/schema/aop 
                  http://www.springframework.org/schema/aop/spring-aop.xsd">
    	<bean id="EbCategoryMainLogic" class="com.jl.eb.logic.EbCategoryMainLogic">
    		<property name="dao">
    			<ref bean="eb_CategoryDAO"/>
    		</property>
    	</bean>
    	<bean id="EbCategoryItemLogic" class="com.jl.eb.logic.EbCategoryItemLogic">
    		<property name="dao">
    			<ref bean="eb_CategoryItemDAO"/>
    		</property>
    		<property name="cateDao">
    			<ref bean="eb_CategoryDAO"/>
    		</property>
    	</bean>
    	<bean id="EbjcClass_Tree" class="com.jl.eb.tree.EbjcClass_Tree">
    		<property name="dao">
    			<ref bean="eb_CategoryDAO"/> 
    		</property>
    	</bean>
    </beans>

  • #2
    and here is my dao and logic code
    dao
    Code:
    package com.jl.eb.dao;
    import java.util.List;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.dao.DataAccessException;
    import org.springframework.orm.jpa.support.JpaDaoSupport;
    import com.jl.framework.db.jpa.callback.JpaQueryCallback;
    public class CategoryDAO extends JpaDaoSupport {
    	private static final Log log = LogFactory.getLog(CategoryDAO.class);
    	private static final String poname= Category.class.getName();
    	public Category query(String id)throws DataAccessException{
    		String  sql ="select po from " + poname + " po where po.id='"+id+"'";
    		List list = null;
    		try{
    			JpaQueryCallback callback = new JpaQueryCallback(sql);
    			list = getJpaTemplate().executeFind(callback);
    		} catch (DataAccessException e) {
    			log.error("Hibernate get enconnt an data error!",e);
    			throw e;
    		}
    		if(list==null ||list.size()==0){
    			return null;
    		}else{
    			return (Category)list.get(0);
    		}		
    	}
    	public Category create(Category entity)throws DataAccessException{
    		try{
    			 getJpaTemplate().persist(entity);			
    		}catch(DataAccessException e){
    			log.error("Hibernate create enconnt an data error!",e);
    			throw e;
    		}
    		 return entity;		
    	}
    	public Category update(Category entity)throws DataAccessException{
    		try{
    			getJpaTemplate().merge(entity);
    		}catch(DataAccessException e){
    			log.error("Hibernate update record enconnt an error!",e);
    			throw e;
    		}
    		return entity;
    	}
    	public boolean delete(String id)throws DataAccessException{
    		try{
    			getJpaTemplate().remove(query(id));
    		}catch(DataAccessException e){
    			log.error("Hibernate delete record enconnt an error!",e);
    			throw e;
    		}
    		return true;
    	}
    	public List findFirstClass(String compId) throws DataAccessException{
    		String  sql ="select po from " + poname + " po where po.compId='"+compId+"' AND po.parentId=''";
    		List list = null;
    		try {
    			JpaQueryCallback jc = new JpaQueryCallback(sql);
    			list = getJpaTemplate().executeFind(jc);
    		} catch (DataAccessException e) {
    			log.error("Entity Manager execute find encount an error!",e);
    			throw e;
    		}
    		return list;
    	}
    	public List findByParentId(String parentId) throws DataAccessException{
    		String sql = "select po from " + poname + " po where po.parentId='" + parentId + "'";
    		List list = null;
    		try {
    			JpaQueryCallback jc = new JpaQueryCallback(sql);
    			list = getJpaTemplate().executeFind(jc);
    		} catch (DataAccessException e) {
    			log.error("Entity Manager execute find encount an error!",e);
    			throw e;
    		}
    		return list;
    	}
    	
    	public Category queryByClassNo(String compId, String classNo){
    		String sql =  "select po from " + poname + " po where po.compId='" + compId + "' AND po.no='" + classNo + "'";
    		List list = null;
    		try{
    			JpaQueryCallback jc = new JpaQueryCallback(sql);
    			list = getJpaTemplate().executeFind(jc);
    		}catch (DataAccessException e) {
    			log.error("Entity Manager execute find encount an error!",e);
    			throw e;
    		}
    		if(list==null ||list.size()==0){
    			return null;
    		}else{
    			return (Category)list.get(0);
    		}
    
    	}
    
    }
    logic ccode
    Code:
    package com.jl.eb.logic;
    import java.util.Date;
    import org.springframework.dao.DataAccessException;
    import org.springframework.transaction.annotation.Transactional;
    import com.jl.eb.dao.Category;
    import com.jl.eb.dao.CategoryDAO;
    
    public class EbCategoryMainLogic {
    	private CategoryDAO dao;	
    	public void setDao(CategoryDAO dao) {this.dao = dao;}
    	@Transactional(readOnly=true)
    	public Category queryByClassNo(String compId, String classNo){
    		if(compId==null || compId.equals("") || classNo==null || classNo.equals("")){
    			return null;
    		}
    		return dao.queryByClassNo(compId,classNo);
    	}
    	@Transactional(readOnly=true)
    	public Category query(String classId){
    		if(classId==null || classId.equals("")){
    			return null;
    		}
    		return dao.query(classId);
    	}
    	@Transactional(readOnly=false)
    	public int create(Category classVo, String compId,String empId){
    		Category c = dao.queryByClassNo(compId,classVo.getNo());
    		if(c!=null){
    			return 0;
    		}
    		classVo.setCompId(compId);
    		classVo.setSysDate(new Date());
    		classVo.setSysEmp(empId);
    		try {
    			dao.create(classVo);
    		} catch (DataAccessException e) {
    			return -1;
    		}
    		return 1;
    	}
    
    	@Transactional(readOnly=false)
    	public int update(Category classVo, String compId,String empId){
    		classVo.setSysEmp(empId);
    		classVo.setCompId(compId);
    		classVo.setSysDate(new Date());
    		try {
    			dao.update(classVo);
    		} catch (DataAccessException e) {
    			return 0;
    		}
    		return 1;
    	}
    	@Transactional(readOnly=false)
    	public int delete(String classId){
    		 if(dao.delete(classId)){
    			 return 1;
    		 }else{
    			 return 0;
    		 }
    	}
    	
    
    }
    my unit test code
    Code:
    package com.jl.eb.test;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import junit.framework.TestCase;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.context.ApplicationContext;
    
    import com.jl.eb.dao.Category;
    import com.jl.eb.dao.CategoryItem;
    import com.jl.eb.logic.EbCategoryItemLogic;
    import com.jl.eb.logic.EbCategoryMainLogic;
    import com.jl.eb.util.EbjcGenId;
    import com.jl.framework.spring.SpringContextLoader;
    
    public class EbCategoryTest extends TestCase {
    	private static final Log log = LogFactory.getLog(EbCategoryTest.class);
    	private ApplicationContext ac ;
    	private String id1 = "";
    	private String id2 = "";
    	private EbCategoryMainLogic  logic;
    	private EbCategoryItemLogic logic2;
    	public void testInsert(){
    		Category c3 = logic.query("f7e725263a383cb0198e4c360be35910");
    		assertEquals(c3.getCategoryItem().size(),3);
    	}
    
    	@Override
    	protected void setUp() throws Exception {
    		super.setUp();
    		SpringContextLoader loader = new SpringContextLoader();
    		ac = loader.createApplicationContext("eb",true);	
    		logic = (EbCategoryMainLogic) ac.getBean("EbCategoryMainLogic");
    		logic2 = (EbCategoryItemLogic) ac.getBean("EbCategoryItemLogic");
    	}
    	@Override
    	protected void tearDown() throws Exception {
    		super.tearDown();
    	}
    
    }
    I got a Lazy Loading Exception:
    Code:
    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.jl.eb.dao.Category.categoryItem, 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.readSize(AbstractPersistentCollection.java:97)
    	at org.hibernate.collection.PersistentSet.size(PersistentSet.java:114)
    	at com.jl.eb.test.EbCategoryTest.testInsert(EbCategoryTest.java:61)
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    	at java.lang.reflect.Method.invoke(Unknown Source)
    	at junit.framework.TestCase.runTest(TestCase.java:154)
    	at junit.framework.TestCase.runBare(TestCase.java:127)
    	at junit.framework.TestResult$1.protect(TestResult.java:106)
    	at junit.framework.TestResult.runProtected(TestResult.java:124)
    	at junit.framework.TestResult.run(TestResult.java:109)
    	at junit.framework.TestCase.run(TestCase.java:118)
    	at junit.framework.TestSuite.runTest(TestSuite.java:208)
    	at junit.framework.TestSuite.run(TestSuite.java:203)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
    and I change the FetchType of Category class to EAGER ,the result is OK
    like this
    [red]@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.EAGER, mappedBy = "category")[/red]
    public Set<CategoryItem> getCategoryItem() {return this.categoryItem;}
    public void setCategoryItem(Set<CategoryItem> categoryItem) {this.categoryItem = categoryItem;}

    What's the problem??

    Comment


    • #3
      The hibernate session is closed straight after calling logic.query

      One option is to look at org.springframework.orm.hibernate3.SessionFactoryU tils and the initDeferredClose method. You can simulate what happens when the OpenSessionInViewInterceptor is used in your test cases.

      I think there's some AbstractTransactionalTestCaseThingy in the spring code somewhere that will automatically roll back your test cases when doing DB tests. Not sure if it also handles the OSIV stuff?? Check that maybe before writing code that calls initDeferredClose

      Comment


      • #4
        I did not use the Test class of spring ,I use the TestCase of JUnit

        and I add the config (below) in to web.xml
        Code:
        <filter>
        		<filter-name>sessionFilter</filter-name>
        		<filter-class>
        			org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter
        		</filter-class>
        		<init-param>
        			<param-name>entityManagerFactoryBeanName</param-name>
        			<param-value>ebEntityManagerFactory</param-value>
        		</init-param>
        	</filter>
        
        	<filter-mapping>
        		<filter-name>sessionFilter</filter-name>
        		<url-pattern>/eb/do*</url-pattern>
        	</filter-mapping>
        Still have the same Exception

        Comment


        • #5
          I find message below in my log:
          Code:
          Candidate advisor [org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor@12bf892] rejected for class [org.springframework.orm.jpa.support.OpenEntityManagerInViewInterceptor]

          Comment


          • #6
            Hi zjnbshifox,
            you are using OpenEntityManagerInViewFilter in web.xml, but it's not valid in the unit test.

            You must extends AbstractTransactionalSpringContextTests to simulete the filter.



            Code:
            public class EbCategoryTest extends AbstractTransactionalSpringContextTests {
            ...
            }

            Comment


            • #7
              There's some information on this here.
              http://www.springframework.org/docs/...tml#testing-tx
              Last edited by karldmoore; Aug 29th, 2007, 11:20 AM.

              Comment

              Working...
              X