1

I already made research about this error but still cannot find appropriate solutions. Here are my codes :

configuration :

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);
    }

}

Models :

    @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...

}

Now in my controller I call the implementation of DAO which causes the exception :

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 "";
        }
    }

}

EDIT :

here is the exception stack :

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

So how to fix the lazy load exception in this case ?

EDIT :

here is implementation of the 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));

    }

}
pheromix
  • 18,213
  • 29
  • 88
  • 158

2 Answers2

1

You need to use a @transactional, LazyInitializationException: failed to lazily initialize a collection of roles, could not initialize proxy - no Session, yo need to have a transaction open yo let hibernate resolve the proxies of collections, try it and comment if it works

Community
  • 1
  • 1
Javier Toja
  • 1,630
  • 1
  • 14
  • 31
  • I updated my question to include the code of the implementation of the DAO ; there is already the @Transactional annotation ! so why does not my code work ? – pheromix Oct 28 '16 at 08:25
  • the txn boundary is only around the DAO. Which means, when your DAO returns, the txn ended, and hence, the corresponding Session is closed. That's why you cannot lazy fetch afterwards. – Adrian Shum Oct 28 '16 at 08:27
  • just shorthand of "transaction" (sorry I though it was a common short form) – Adrian Shum Oct 28 '16 at 08:29
  • I added the @Transactional annotation before the controller method , then I got a long error stack containing `at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:150) at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112)` – pheromix Oct 28 '16 at 08:42
  • try implementing Serializable, add this interface to your entities to be able to serialize and send over the network – Javier Toja Oct 28 '16 at 08:46
  • I implemented Serializable to all entities but I got the same long error stack ! – pheromix Oct 28 '16 at 09:02
  • check this, it may be helpful http://stackoverflow.com/questions/8038718/serializing-generic-java-object-to-json-using-jackson – Javier Toja Oct 28 '16 at 10:15
  • I tried adding the @JsonIgnore annotation but it does not work ! thank you anyway – pheromix Oct 28 '16 at 10:40
0

I created the query with standard sql createSQLQuery but not with Hibernate createQuery , and dataTable knows the index columns !

pheromix
  • 18,213
  • 29
  • 88
  • 158