org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话? [英] org.hibernate.LazyInitializationException: could not initialize proxy - no Session?

查看:148
本文介绍了org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从数据库中的一个对象中做一个简单的加载,但我得到错误无法初始化代理 - 没有会话,任何想法?谢谢

  org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话
org.hibernate.proxy.AbstractLazyInitializer。初始化(AbstractLazyInitializer.jav a:167)
org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java :190)
com.myapp.domain.User _ $$ _ javassist_0.getLogin(User _ $$ _ javassist_0.java)
com.myapp.validator.UserFormValidator.validate(UserFormValidator.java:34)






  @Component 
public class UserFormValidator实现Validator {

@Autowired
private UserDAO userDAO;

@Override
public boolean supports(Class<> clazz){
return UserForm.class.equals(clazz);
}

public UserDAO getUserDAO(){
return userDAO;
}

public void setUserDAO(UserDAO userDAO){
this.userDAO = userDAO;

$ b @Override $ b $ public void validate(Object target,Errors errors){
User user =(User)getUserDAO()。findById(new Integer(1 ));
System.out.println(User - >+ user.getLogin());







  @Transactional 
public class GenericDAOHibernateImpl< T,PK extends Serializable>
实现GenericDAO< T,PK> {

public GenericDAOHibernateImpl(){
super();
}

私人课程< T>类型;

@Resource(name =sessionFactory)
private SessionFactory sessionFactory;

public GenericDAOHibernateImpl(Class< T> type){
this.type = type;
}

public void saveOrUpdate(T object){
getSession()。save(object);


public Object findById(Serializable id){
return getSession()。load(type,id);
}

保护会话getSession(){
return sessionFactory.getCurrentSession();







 <?xml version =1.0encoding =UTF-8?> 
< beans xmlns =http://www.springframework.org/schema/beans
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instance
xmlns:p =http://www.springframework.org/schema/p
xmlns:tx =http://www.springframework.org/schema/tx
xmlns :context =http://www.springframework.org/schema/context
xsi:schemaLocation =
http://www.springframework.org/schema/beans
http: //www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/ schema / tx / spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context- 3.0.xsd
>

< context:property-placeholder location =/ WEB-INF / jdbc.properties/>

<! - 启用管理交易的注释风格 - >
< tx:注解驱动的事务管理器=transactionManager/>

<! - 声明用于检索Hibernate会话的Hibernate SessionFactory - >
<! - 请参阅http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/orm/hibernate3/annotation/AnnotationSessionFactoryBean.html - >
<! - 请参阅http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/SessionFactory.html - >
<! - 请参阅http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/Session.html - >

p:dataSource-ref =dataSource
p:configLocation = classpath:hibernate.cfg.xml
p:packagesToScan =com.myapp.domain/>

< bean id =dataSourceclass =com.mchange.v2.c3p0.ComboPooledDataSource
destroy-method =close
p:driverClass =$ { jdbc.driverClassName}
p:jdbcUrl =$ {jdbc.url}
p:user =$ {jdbc.username}
p:password =$ {jdbc.password}
p:acquireIncrement =5
p:idleConnectionTestPeriod =60
p:maxPoolSize =100
p:maxStatements =50
p:minPoolSize =10
/>


<! - 声明一个事务管理器 - >
< bean id =transactionManagerclass =org.springframework.orm.hibernate3.HibernateTransactionManager
p:sessionFactory-ref =sessionFactory/>






  @Entity 
@Table(name =USER)
public class User extends appEntity {

@Id
@Column(name =USER_ID,unique = true,nullable = false)
private Integer id;
@Column(name =LOGIN)
私人字符串登录;
@Column(name =PASSWORD)
私人字符串密码;


public String getLogin(){
return login;
}
public void setLogin(String login){
this.login = login;
}

public Integer getId(){
return id;
}
public void setId(Integer id){
this.id = id;
}
public String getPassword(){
return password;
}
public void setPassword(String password){
this.password = password;


解决方案

尝试添加<$ c

$ $ $ $ $ b $ @ $ {
@Transactional($ c $ @ $> @Transactional readOnly = true)
public void validate(Object target,Errors errors){
...
}

会发生什么情况是因为没有 @Transactional 注释,所以没有与该方法关联的会话,并且每个查询都将运行它是自己的会话,然后立即关闭。



方法 session.load()总是返回一个代理,不像 session.get()(请参阅负载与获取之间的差异)。所以代理被返回,但由于缺少 @Transactional ,创建代理的会话立即关闭。当代理首次被访问时,它的session被关闭,所以我们得到'no session'错误。



如果你从 load ) get()只会部分解决问题,因为如果在尝试加载例如一个惰性初始化集合之后,异常再次发生。

在业务方法中添加 @Transactional 将确保在持续时间内存在相同的会话的方法调用,并防止发生这种和其他相关的错误。


I am trying to make a simple load from an object from the DB, but i got the error "could not initialize proxy - no Session", Any idea ? Thanks

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.jav a:167)
    org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:215)
    org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:190)
    com.myapp.domain.User_$$_javassist_0.getLogin(User_$$_javassist_0.java)
    com.myapp.validator.UserFormValidator.validate(UserFormValidator.java:34)


@Component 
public class UserFormValidator implements Validator {

@Autowired
private UserDAO userDAO;  

@Override
public boolean supports(Class<?> clazz) {
    return UserForm.class.equals(clazz);
}

public UserDAO getUserDAO() {
    return userDAO;
}

public void setUserDAO(UserDAO userDAO) {
    this.userDAO = userDAO;
}

@Override
public void validate(Object target, Errors errors) {
    User user = (User)getUserDAO().findById(new Integer(1));
    System.out.println ("User -> " + user.getLogin());
}
}


@Transactional
public class GenericDAOHibernateImpl <T, PK extends Serializable>
implements GenericDAO<T, PK> {

public GenericDAOHibernateImpl() {
    super();
}

private Class<T> type;

@Resource(name = "sessionFactory")
private SessionFactory sessionFactory;

public GenericDAOHibernateImpl(Class<T> type) {
    this.type = type;
}

public void saveOrUpdate(T object) {
    getSession().save(object);
}

public Object findById(Serializable id) {
     return getSession().load(type, id);
}

protected Session getSession() {
    return sessionFactory.getCurrentSession();
}
}


<?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:p="http://www.springframework.org/schema/p" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        ">

<context:property-placeholder location="/WEB-INF/jdbc.properties" />

<!-- Enable annotation style of managing transactions -->
<tx:annotation-driven transaction-manager="transactionManager" />   

<!-- Declare the Hibernate SessionFactory for retrieving Hibernate sessions -->
<!-- See http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/orm/hibernate3/annotation/AnnotationSessionFactoryBean.html -->                           
<!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/SessionFactory.html -->
<!-- See http://docs.jboss.org/hibernate/stable/core/api/index.html?org/hibernate/Session.html -->

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
             p:dataSource-ref="dataSource"
             p:configLocation="classpath:hibernate.cfg.xml"
             p:packagesToScan="com.myapp.domain"/>  

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" 
destroy-method="close" 
p:driverClass="${jdbc.driverClassName}" 
p:jdbcUrl="${jdbc.url}"
p:user="${jdbc.username}"
p:password="${jdbc.password}"
p:acquireIncrement="5"
            p:idleConnectionTestPeriod="60"
            p:maxPoolSize="100"
            p:maxStatements="50"
            p:minPoolSize="10" 
/>


<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" 
            p:sessionFactory-ref="sessionFactory" />


@Entity
@Table(name="USER")
public class User extends appEntity {

@Id
@Column(name = "USER_ID", unique = true, nullable = false)
private Integer id;
@Column(name = "LOGIN")
private String login;
@Column(name = "PASSWORD")
private String password;


public String getLogin() {
    return login;
}
public void setLogin(String login) {
    this.login = login;
}

public Integer getId() {
    return id;
}
public void setId(Integer id) {
    this.id = id;
}
public String getPassword() {
    return password;
}
public void setPassword(String password) {
    this.password = password;
}

解决方案

Try to add @Transactional to the validate method:

@Override
@Transactional(readOnly=true)
public void validate(Object target, Errors errors) {
    ...
}

What happens is that because there is no @Transactional annotation, there is no session associated to the method, and each query will run in it's own session that is closed immediately afterwards.

The method session.load() always returns a proxy, unlike session.get() (see here for differences between load vs get).

So the proxy is returned, but due to the missing @Transactional the session that created the proxy is immediately closed. When the proxy is accessed the first time, it's session is closed so we get the 'no session' error.

If you change from load() to get() that will only partially solve the problem, because if after the get you try to load for example a lazy initialized collection, the exception occurs again.

Adding @Transactional to the business method will ensure the presence of the same session for the duration of the method call, and prevent the occurrence of this and other related errors.

这篇关于org.hibernate.LazyInitializationException:无法初始化代理 - 没有会话?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆