[SPRING] org.hibernate.LazyInitializationException : 프록시를 초기화 할 수 없습니다 - 세션이 없습니까?
SPRINGorg.hibernate.LazyInitializationException : 프록시를 초기화 할 수 없습니다 - 세션이 없습니까?
내가 DB에서 개체에서 간단한로드를 만들려고하지만 오류가 "프록시 초기화 할 수 없습니다 - 세션 없음", 어떤 생각? 감사
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;
}
해결법
-
==============================
1.validate 메소드에 @Transactional을 추가하십시오.
validate 메소드에 @Transactional을 추가하십시오.
@Override @Transactional(readOnly=true) public void validate(Object target, Errors errors) { ... }
무슨 일이 일어나는가는 @Transactional 어노테이션이 없기 때문에 메서드에 연결된 세션이 없으며 각 쿼리는 즉시 닫힌 자체 세션에서 실행됩니다.
session.get ()과 달리 session.load () 메서드는 항상 프록시를 반환합니다 (로드 대 get의 차이점은 여기 참조).
따라서 프록시가 반환되지만, @Transactional이 없기 때문에 프록시를 만든 세션은 즉시 닫힙니다. 처음으로 프록시에 액세스하면 세션이 닫혀 'no session'오류가 발생합니다.
load ()에서 get ()으로 변경하면 문제가 부분적으로 만 해결됩니다. 예를 들어 게으른 초기화 된 컬렉션을로드하려고 시도한 후에 예외가 다시 발생하기 때문입니다.
비즈니스 메서드에 @Transactional을 추가하면 메서드 호출 동안 동일한 세션이 존재하게되어이 오류 및 기타 관련 오류가 발생하지 않습니다.
from https://stackoverflow.com/questions/22439306/org-hibernate-lazyinitializationexception-could-not-initialize-proxy-no-sessi by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring MappingJacksonJsonView, JSP 뷰 대신 사용하는 법을 가르쳐주세요. (0) | 2019.03.31 |
---|---|
[SPRING] Jackson2ObjectMapperBuilder를 사용하여 필드 가시성 ANY (0) | 2019.03.31 |
[SPRING] 여러 데이터베이스 작업에 Spring JdbcTemplate 사용 (0) | 2019.03.31 |
[SPRING] Tuckey UrlRewrite Filter가 규칙이 일치 한 후 chain.doFilter를 호출하지 않는 이유는 무엇입니까? (0) | 2019.03.31 |
[SPRING] 스프링 보안 - 메소드 보안 주석을 어떻게 사용할 수 있습니까? (0) | 2019.03.31 |