江湖救急,各位大侠帮帮忙!JUnit测试延迟加载抛异常:LazyInitializationException:no Session

zaikooLu 2012-01-08 10:24:03
hibernate查询关联属性报错,查找某student的class时发生以上情景

//JUnit
@Test
public void test4Lazy(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
StudentService studentService = (StudentService)context.getBean("studentService");
Student stu=studentService.getStudentById(1);
System.out.println();
Clazz clazz=stu.getClazz();
System.out.println(clazz.getName());
}

//班级类
@Entity
@Table(name="t_class")
public class Clazz {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private String name;
。。。
}

//学生类
@Entity
@Table(name="t_student")
public class Student {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
private Integer no;
private String name;
private String sex;

@ManyToOne(fetch=FetchType.LAZY)//使用延迟加载
@JoinColumn(name="class_id")
private Clazz clazz;
。。。
}

//学生dao
@Repository("studentDao")
public class StudentDaoImpl extends BaseDao implements StudentDao {
public Student findStudentById(final Integer id){
Student stu=(Student) this.hibernateTemplate.get(Student.class, id);
System.out.println();
return stu;

}

}

//学生service
@Component("studentService")
public class StudentServiceImpl implements StudentService {
@Resource(name="studentDao")
private StudentDao studentDao;

public Student getStudentById(Integer id){
Student stu=this.studentDao.findStudentById(id);
//DEBUG - Closing Hibernate Session
System.out.println();
return stu;
}
。。。
}

//beans.xml事务部分
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="add*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>

<aop:config>
<aop:pointcut id="dao" expression="execution(public * com.smonk.menu.dao.*.*(..))" />
<aop:advisor pointcut-ref="dao" advice-ref="txAdvice" />
</aop:config>


//----------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------------------
clazz为student的关联属性,使用延迟加载
JUnit测试时抛异常:
ERROR - could not initialize proxy - no Session
org.hibernate.LazyInitializationException: could not initialize proxy - no Session


请问如何扩大session的生命周期?
session在dao执行完成后关闭,同时事务也关闭了

请问可以使用@PersistenceContext扩大session范围吗?

LIE也算是hibernate的一大顽疾,希望各位大侠能够给点建设性意见!
资料我也查了,试了都不行,希望大家不要轻易Ctrl+V!

谢谢!

...全文
239 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
dracularking 2012-01-08
  • 打赏
  • 举报
回复
The problem is that you are trying to access a collection in an object that is detached. You need to re-attach the object before accessing the collection to the current session. You can do that through

session.update(object);

Using lazy=false is not a good solution because you are throwing away the Lazy Initialization feature of hibernate. When lazy=false, the collection is loaded in memory at the same time that the object is requested. This means that if we have a collection with 1000 items, they all will be loaded in memory, despite we are going to access them or not. And this is not good.

Please read this article where it explains the problem, the possible solutions and why is implemented this way. Also, to understand Sessions and Transactions you must read this other article.

访问的对象已经是detached状态就会出现这种状况
我不知道延长session时间是否可行。它说的是re-attach该对象到当前session

关于detached状态
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/objectstate.html
zaikooLu 2012-01-08
  • 打赏
  • 举报
回复
也就是说有两个方法:
1、扩大session范围
2、重新打开一个session来做关联查询

思路是正确的。
但是:关联查询不同于update,
关联查询调用的是Pojo的get关联实体的方法(如:Student的getClazz),
而update前提是已经有session了

现在的问题是如何调用getClazz时让hibernate重新打开一个session?

13,100

社区成员

发帖
与我相关
我的任务
社区描述
Java J2ME
社区管理员
  • J2ME社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧