2016-10-28 92 views
0

我已经对此错误进行了研究,但仍找不到合适的解决方案。这里是我的代码:hibernate.LazyInitializationException:无法长期初始化角色集合

配置:

package com.ambre.pta.config; 

import javax.sql.DataSource; 

import org.apache.commons.dbcp2.BasicDataSource; 
import org.hibernate.SessionFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.PropertySource; 
import org.springframework.context.annotation.PropertySources; 
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; 
import org.springframework.orm.hibernate4.HibernateTransactionManager; 
import org.springframework.orm.hibernate4.LocalSessionFactoryBuilder; 
import org.springframework.transaction.annotation.EnableTransactionManagement; 
import org.springframework.web.servlet.view.InternalResourceViewResolver; 

import com.ambre.pta.dao.MenuDAO; 
import com.ambre.pta.dao.MenuDAOImpl; 
import com.ambre.pta.dao.RoleDAO; 
import com.ambre.pta.dao.RoleDAOImpl; 
import com.ambre.pta.dao.UtilisateurDAO; 
import com.ambre.pta.dao.UtilisateurDAOImpl; 


@Configuration 
@ComponentScan("com.ambre.pta") 
@EnableTransactionManagement 
@PropertySources({ 
    @PropertySource("classpath:fr/global.properties"), 
    @PropertySource("classpath:fr/main.properties"), 
    @PropertySource("classpath:fr/admin.properties"), 
    @PropertySource("classpath:fr/referentiel.properties") 
}) 
public class ApplicationContextConfig { 

    @Bean 
    public static PropertySourcesPlaceholderConfigurer properties() { 
     return new PropertySourcesPlaceholderConfigurer(); 
    } 

    @Bean(name = "viewResolver") 
    public InternalResourceViewResolver getViewResolver() { 
     InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 
     viewResolver.setPrefix("/WEB-INF/views/"); 
     viewResolver.setSuffix(".jsp"); 
     return viewResolver; 
    } 

    @Bean(name = "dataSource") 
    public DataSource getDataSource() { 
     BasicDataSource dataSource = new BasicDataSource(); 
     dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver"); 
     dataSource.setUrl("jdbc:oracle:thin:@localhost:1521:xe"); 
     dataSource.setUsername("pta"); 
     dataSource.setPassword("pta"); 

     return dataSource; 
    } 

    @Autowired 
    @Bean(name = "sessionFactory") 
    public SessionFactory getSessionFactory(DataSource dataSource) { 

     LocalSessionFactoryBuilder sessionBuilder = new LocalSessionFactoryBuilder(dataSource); 

     sessionBuilder.scanPackages("com.ambre.pta.model"); 

     return sessionBuilder.buildSessionFactory(); 

    } 

    @Autowired 
    @Bean(name = "transactionManager") 
    public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) { 

     HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory); 

     return transactionManager; 
    } 

    @Autowired 
    @Bean(name = "utilisateurDao") 
    public UtilisateurDAO getUtilisateurDao(SessionFactory sessionFactory) { 
     return new UtilisateurDAOImpl(sessionFactory); 
    } 

    @Autowired 
    @Bean(name = "menuDao") 
    public MenuDAO getMenuDao(SessionFactory sessionFactory) { 
     return new MenuDAOImpl(sessionFactory); 
    } 

    @Autowired 
    @Bean(name = "roleDao") 
    public RoleDAO getRoleDao(SessionFactory sessionFactory) { 
     return new RoleDAOImpl(sessionFactory); 
    } 

} 

型号:

@Entity 
    @Table(name = "menu") 
    public class Menu { 

     @Id 
     @SequenceGenerator(name="s_menu", sequenceName="s_menu", allocationSize=1) 
     @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s_menu") 
     private int menu_id; 

     private Integer gmnu_code; 

     private String menu_lib; 

     private Integer menu_ordre; 

     private Integer menu_visible; 

     private Integer menu_deleted; 

     private Integer menu_parent; 

     private String menu_controlleur; 

     private String menu_navigation; 

     @ManyToMany(cascade = CascadeType.ALL) 
     @JoinTable(name = "role_menu", joinColumns = { @JoinColumn(name = "menu_id") }, inverseJoinColumns = { @JoinColumn(name = "role_code") }) 
     private Set<Role> roles = new HashSet<Role>(); 

     public Menu() { 
      super(); 
     } 

     public Menu(Integer gmnu_code, String menu_lib, Integer menu_ordre, Integer menu_visible, Integer menu_deleted, Integer menu_parent, String menu_controlleur, String menu_navigation) { 
      super(); 
      this.gmnu_code = gmnu_code; 
      this.menu_lib = menu_lib; 
      this.menu_ordre = menu_ordre; 
      this.menu_visible = menu_visible; 
      this.menu_deleted = menu_deleted; 
      this.menu_parent = menu_parent; 
      this.menu_controlleur = menu_controlleur; 
      this.menu_navigation = menu_navigation; 
     } 

     public Menu(Integer gmnu_code, String menu_lib, Integer menu_ordre, Integer menu_visible, Integer menu_deleted, Integer menu_parent, String menu_controlleur, String menu_navigation, Set<Role> roles) { 
      super(); 
      this.gmnu_code = gmnu_code; 
      this.menu_lib = menu_lib; 
      this.menu_ordre = menu_ordre; 
      this.menu_visible = menu_visible; 
      this.menu_deleted = menu_deleted; 
      this.menu_parent = menu_parent; 
      this.menu_controlleur = menu_controlleur; 
      this.menu_navigation = menu_navigation; 
      this.roles = roles; 
     } 

     // getters and setters.... 

    } 

@Entity 
@Table(name = "utilisateur") 
public class Utilisateur { 

    @Id 
    @SequenceGenerator(name="s_utilisateur", sequenceName="s_utilisateur", allocationSize=1) 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="s_utilisateur") 
    private int user_code; 

    @Formula(value="user_nom || ' ' || user_prenom") 
    private String noms; 

    private String user_nom; 

    private String user_prenom; 

    private String user_login; 

    private String user_passwd; 

    private String user_email; 

    private Integer user_deleted; 

    @ManyToMany(cascade = CascadeType.ALL) 
    @JoinTable(name = "role_user", joinColumns = { @JoinColumn(name = "user_code") }, inverseJoinColumns = { @JoinColumn(name = "role_code") }) 
    private Set<Role> roles = new HashSet<Role>(); 

    public Utilisateur() { 
     super(); 
    } 

    public Utilisateur(String user_nom, String user_prenom, String user_login, String user_passwd, String user_email, Integer user_deleted) { 
     super(); 
     this.user_nom = user_nom; 
     this.user_prenom = user_prenom; 
     this.user_login = user_login; 
     this.user_passwd = user_passwd; 
     this.user_email = user_email; 
     this.user_deleted = user_deleted; 
    } 

    public Utilisateur(String noms, String user_nom, String user_prenom, String user_login, String user_passwd, String user_email, Integer user_deleted, Set<Role> roles) { 
     super(); 
     this.noms = noms; 
     this.user_nom = user_nom; 
     this.user_prenom = user_prenom; 
     this.user_login = user_login; 
     this.user_passwd = user_passwd; 
     this.user_email = user_email; 
     this.user_deleted = user_deleted; 
     this.roles = roles; 
    } 

    // getters and setters... 

} 

@Entity 
@Table(name = "role") 
public class Role { 

    @Id 
    private String role_code; 

    private String role_lib; 

    @ManyToMany(mappedBy = "roles") 
    private Set<Menu> menus = new HashSet<Menu>(); 

    @ManyToMany(mappedBy = "roles") 
    private Set<Utilisateur> users = new HashSet<Utilisateur>(); 

    public Role() { 
     super(); 
    } 

    public Role(String role_lib) { 
     super(); 
     this.role_lib = role_lib; 
    } 

    public Role(String role_lib, Set<Menu> menus) { 
     super(); 
     this.role_lib = role_lib; 
     this.menus = menus; 
    } 

    // getters and setters... 

} 

现在在我的控制我叫DAO的执行导致异常:

import java.io.IOException; 
import java.util.List; 

import javax.servlet.http.HttpServletRequest; 

import org.codehaus.jackson.JsonGenerationException; 
import org.codehaus.jackson.map.JsonMappingException; 
import org.codehaus.jackson.map.ObjectMapper; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.core.env.Environment; 
import org.springframework.stereotype.Controller; 
import org.springframework.ui.Model; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.ResponseBody; 

import com.ambre.pta.dao.MenuDAO; 
import com.ambre.pta.dao.RoleDAO; 
import com.ambre.pta.model.DataTablesTO; 
import com.ambre.pta.model.Role; 

@Controller 
@RequestMapping("/adminrole") 
public class AdminRole { 

    @Autowired 
    private Environment env; 

    @Autowired 
    private MenuDAO menuDao; 

    @Autowired 
    private RoleDAO roleDao; 

    @RequestMapping(value = "/ajaxDataTableListRoles", produces = "application/json") 
    @ResponseBody 
    public String ajaxListRole(@RequestParam int draw, @RequestParam int start, @RequestParam int length, 
           @RequestParam("search[value]") String search, @RequestParam("order[0][column]") int triIdx, @RequestParam("order[0][dir]") String ordreTri) 
    { 

     List<Role> rolesDataTable = roleDao.list(start, length, search, triIdx, ordreTri); 
     List<Role> rolesAll = roleDao.list(); 
     DataTablesTO<Role> dt = new DataTablesTO<Role>(); 
     dt.setData(rolesDataTable); 
     dt.setDraw(draw); 
     if (search == null || search.equals("")) { 
      dt.setRecordsTotal(rolesAll.size()); 
      dt.setRecordsFiltered(rolesAll.size()); 
     } 
     else { 
      dt.setRecordsTotal(rolesDataTable.size()); 
      dt.setRecordsFiltered(roleDao.nbRoleTotalFiltered(search)); 
     } 

     ObjectMapper mapper = new ObjectMapper(); 

     try { 
      return mapper.writeValueAsString(dt); 
     } catch (JsonGenerationException e) { 
      e.printStackTrace(); 
      return ""; 
     } catch (JsonMappingException e) { 
      e.printStackTrace(); 
      return ""; 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return ""; 
     } 
    } 

} 

编辑:

这里是异常堆栈:

org.codehaus.jackson.map.JsonMappingException: failed to lazily initialize a collection of role: com.ambre.pta.model.Role.menus, could not initialize proxy - no Session (through reference chain: com.ambre.pta.model.DataTablesTO["data"]->java.util.ArrayList[0]->com.ambre.pta.model.Role["menus"]) 
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218) 
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183) 
    at org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140) 
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:158) 
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) 
    at org.codehaus.jackson.map.ser.std.StdContainerSerializers$IndexedListSerializer.serializeContents(StdContainerSerializers.java:122) 
    at org.codehaus.jackson.map.ser.std.StdContainerSerializers$IndexedListSerializer.serializeContents(StdContainerSerializers.java:71) 
    at org.codehaus.jackson.map.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:86) 
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446) 
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) 
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) 
    at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610) 
    at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256) 
    at org.codehaus.jackson.map.ObjectMapper._configAndWriteValue(ObjectMapper.java:2575) 
    at org.codehaus.jackson.map.ObjectMapper.writeValueAsString(ObjectMapper.java:2097) 
    at com.ambre.pta.controller.AdminRole.ajaxListRole(AdminRole.java:77) 
    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 org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:285) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Unknown Source) 
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.ambre.pta.model.Role.menus, could not initialize proxy - no Session 
    at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:575) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:214) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:554) 
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:142) 
    at org.hibernate.collection.internal.PersistentSet.iterator(PersistentSet.java:180) 
    at org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:45) 
    at org.codehaus.jackson.map.ser.std.CollectionSerializer.serializeContents(CollectionSerializer.java:23) 
    at org.codehaus.jackson.map.ser.std.AsArraySerializerBase.serialize(AsArraySerializerBase.java:86) 
    at org.codehaus.jackson.map.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:446) 
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) 
    ... 49 more 

那么如何解决在这种情况下延迟加载异常?

编辑:

这里是实现DAO的:

public class RoleDAOImpl implements RoleDAO { 

    @Autowired 
    private SessionFactory sessionFactory; 

    public RoleDAOImpl() { 
     super(); 
    } 

    public RoleDAOImpl(SessionFactory sessionFactory) { 
     super(); 
     this.sessionFactory = sessionFactory; 
    } 

    @Override 
    @Transactional 
    public List<Role> list() { 

     @SuppressWarnings("unchecked") 
     List<Role> listRole = (List<Role>) sessionFactory.getCurrentSession() 
                 .createCriteria(Role.class) 
                 .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list(); 
     return listRole; 

    } 

    @Override 
    @Transactional 
    public List<Role> list(int start, int length, String search, int triIdx, String ordreTri) { 

     String hql = "select r from Role r"; 

     if (search != null && !search.equals("")) { 

      hql = hql.concat(" where "); 

      hql = hql.concat(" lower(r.role_lib) like '%").concat(search.toLowerCase()).concat("%'"); 

     } 

     if (ordreTri.equals("asc")) { 

      switch (triIdx) { 
       case 0: 
        hql = hql.concat(" order by r.role_lib "); 
        break; 
       default: 
        hql = hql.concat(" order by r.role_lib "); 
        break; 
      } 

     } else { 

      switch (triIdx) { 
       case 0: 
        hql = hql.concat(" order by r.role_lib desc"); 
        break; 
       default: 
        hql = hql.concat(" order by r.role_lib desc"); 
        break; 
      } 
     } 

     Query query = sessionFactory.getCurrentSession().createQuery(hql); 
     query = query.setFirstResult(start); 
     query = query.setMaxResults(length); 

     @SuppressWarnings("unchecked") 
     List<Role> listRole = (List<Role>) query.list(); 

     return listRole; 

    } 

    @Override 
    @Transactional 
    public int nbRoleTotalFiltered(String search) { 

     String hql = "select r from Role r"; 

     if (search != null && !search.equals("")) { 

      hql = hql.concat(" where "); 

      hql = hql.concat(" lower(r.role_lib) like '%").concat(search.toLowerCase()).concat("%'"); 

     } 

     Query query = sessionFactory.getCurrentSession().createQuery(hql); 

     @SuppressWarnings("unchecked") 
     List<Role> listRole = (List<Role>) query.list(); 

     return listRole.size(); 

    } 

    @Override 
    @Transactional 
    public Role get(String role_code) { 

     return (Role) sessionFactory.getCurrentSession().get(Role.class, role_code); 

    } 

    @Override 
    @Transactional 
    public void saveOrUpdate(Role role) { 

     Session sess = sessionFactory.getCurrentSession(); 
     sess.saveOrUpdate(role); 

    } 

    @Override 
    @Transactional 
    public void delete(String role_code) { 

     sessionFactory.getCurrentSession().delete((Role) sessionFactory.getCurrentSession().get(Role.class, role_code)); 

    } 

} 

回答

0

您需要使用@Transactional,LazyInitializationException: failed to lazily initialize a collection of roles, could not initialize proxy - no Session,哟需要有一个事务打开哟让Hibernate解决的代理收集,尝试它并评论它是否工作

+0

我更新了我的问题以包含DAO的实现代码;已经有了@Transactional注解!那为什么我的代码不工作? – pheromix

+0

txn边界只在DAO附近。这意味着,当您的DAO返回时,txn结束,因此相应的会话关闭。这就是为什么你不能懒后取。 –

+0

只是“事务”的简写(对不起,虽然它是一个常见的简写形式) –

0

我使用标准sql createSQLQuery创建了查询,但没有使用Hibernate createQuery,并且dataTable知道索引colu mns!

相关问题