2014-03-30 3 views
0

나는 이것에 너무 많은 시간을 낭비했다. 여기에 물어볼 시간이다. 고마워.@Transactional로 Hibernate Lazy 초기화 예외

Frameworkds : SpringMVC 4 + 내가을 기대 3.6.0

최대 절전 모드 : JSP 페이지

내 구성

개체 (많은 일을)를 뽀조를 표시 1.applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans.xsd"> 

    <bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource"> 
     <property name="driver" value="com.mysql.jdbc.Driver"/> 
     <property name="driverUrl" value="jdbc:mysql://localhost:3306/xxx"/> 
     <property name="user" value="-"/> 
     <property name="password" value="-"/> 
     <property name="maximumConnectionCount" value="10"/> 
     <property name="minimumConnectionCount" value="5"/> 
    </bean> 
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
     <property name="packagesToScan" value="com.test.pojo"/> 
     <property name="dataSource" ref="dataSource"/> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
       <prop key="hibernate.show_sql">true</prop> 
       <prop key="hibernate.hbm2ddl.auto">update</prop> 
       <!-- auto generate table --> 
      </props> 
     </property> 
    </bean> 
</beans> 
.Controller

@Transactional 
@Controller 
public class TESTS { 

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

    @RequestMapping("/hello") 
    public ModelAndView test(){ 
     ModelAndView mv = new ModelAndView(); 
     mv.setViewName("/hello"); 
     mv.addObject("master", (Master) sessionFactory.getCurrentSession().createQuery("from Master where master_id = 1").uniqueResult()); 
     return mv; 
    } 
} 

4.Pojos

public class Master { 
    @Id 
    @GeneratedValue 
    private Integer master_id; 
    private String master_name; 

    @OneToMany(fetch = FetchType.LAZY, mappedBy="master", cascade = CascadeType.ALL,orphanRemoval=true) 
    private List<Pet> pets; 
} 

public class Pet { 

    @Id 
    @GeneratedValue 
    private Integer id; 

    private String name; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "master_id", nullable = false) 
    private Master master; 
} 

63,210

2.dispatcher-servlet.xml에

<?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:mvc="http://www.springframework.org/schema/mvc" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:tx="http://www.springframework.org/schema/tx" 

     xmlns:task="http://www.springframework.org/schema/task" 

     xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans.xsd 
          http://www.springframework.org/schema/mvc 
          http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd 
          http://www.springframework.org/schema/context 
          http://www.springframework.org/schema/context/spring-context-3.1.xsd 
          http://www.springframework.org/schema/tx 
          http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 

          http://www.springframework.org/schema/task 
          http://www.springframework.org/schema/task/spring-task-3.0.xsd"> 



    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory" /> 
    </bean> 

    <tx:annotation-driven transaction-manager="transactionManager" /> 

    <task:annotation-driven /> 

    <mvc:annotation-driven /> 

    <context:component-scan base-package="com.test.module" /> 

    <!--HandlerMapping--> 
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/> 

    <!--HandlerAdapter--> 
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/> 

    <!--ViewResolver --> 
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> 
     <property name="prefix" value="/views/" /> 
     <property name="suffix" value=".jsp" /> 
    </bean> 

</beans> 

심지어 내가 앞서 @Controller를 @Transnational 주석을 넣어, 난 여전히 '수 애완 동물의 정보를 얻는다. 항상 예외를 얻는다. '지연 컬렉션을 초기화하지 못했습니다. com.test.pojo.Master.pets, 세션이나 세션이 닫히지 않았습니다.'

감사합니다.

답변

1

예외가이 모든 것을 말합니다. JSP에서 느슨하게로드 된 콜렉션에 액세스하려고합니다. JSP가 실행되면 컨트롤러의 트랜잭션 메소드가 리턴되고 트랜잭션과 관련 세션이 닫힙니다. 따라서 Hibernate는 더 이상 콜렉션을로드 할 수 없다.

컨트롤러에서 컬렉션을로드하거나 OpenSessionInViewFilter 또는 OpenSessionInViewInterceptor를 사용해야합니다. 하나의

  • master.getPets().size() (또는 컬렉션의 기타 방식), 또는
  • Hibernate.initialize(master.getPets()) 또는
  • 로드 마스터 및 애완

    컨트롤러로부터 수집로드하려면 질의 : select m from Master m left join fetch m.pets where...

주의는 단순히 매스를 얻기 위해 session.get()를 사용해야 할 때 현재 코드는 쿼리를 사용 ID별로.

0
You have put **"fetch = FetchType.LAZY"**, while mapping pets, so hibernate will just load the proxies for Object "Pets" . 
Either yo can make it to **"fetch = FetchType.EAGER"**, with only drawback that Hibernate will always load "Pets object" along with master object even if you do not need. 
So better way is to intialize using Hibernate 

**Hibernate.initialize(master.getPets()),**