简体   繁体   中英

org.hibernate.LazyInitializationException: could not initialize proxy - no Session again

I know that my question very strange and difficult to understand

I create some structure of my project. But every time I faced with different problems as could not initialize proxy - No session again or Not serializable exception

I want to get some advice or help. I try to use annotation transactional and I don't understand in which case I should use implements Serializable . Of course, I know that if I want to use bean with view scope I should use client saving method and bean should be implenebts seriailzable. If I user other non-primitive fields its also should be serializable. It means that using inmplenets Serializable in both interfaces IDao and ITestSystemService nothing bad.

My generic DAO

public interface IDao<T> extends Serializable{
    List<T> getAll() throws DAOException;
    T get(Long id) throws DAOException;
}

DAO implementation

@Repository("subjectDAO")
@Scope("prototype")
public class SubjectHibernateDAO implements ISubjectDAO{

    private static final long serialVersionUID = 1L;

    private static final Logger logger = Logger.getLogger(SubjectHibernateDAO.class);

    @Autowired
    private SessionFactory hibernateSessionFactory;
    //getter and setter

    @SuppressWarnings("unchecked")
    @Override
    public List<Subject> getAll() throws DAOException {
        Session session = hibernateSessionFactory.getCurrentSession();

        Transaction transaction = null;
        List<Subject> subjectList = null;
        try{
            transaction = session.beginTransaction();
            subjectList = session.getNamedQuery(GET_ALL_SUBJECTS_NAME_QUERY).list();
            transaction.commit();
        }  catch (HibernateException e) {
            if (transaction != null)
                transaction.rollback();
            logger.error(SQL_EXCEPTION_IN_QUERY, e);
            throw new DAOException(SQL_EXCEPTION_IN_QUERY, e);
        }
        return subjectList;
    }

// Generic service interface
public interface ITestSystemService<T> extends Serializable{

    List<T> getAll() throws DAOException;
}

//Service realization
@Service("subjectService")
@SessionScoped
public class SubjectServiceImpl implements ISubjectService{

    private static final long serialVersionUID = 1L;

    @Autowired
    @Qualifier("subjectDAO")
    private IDao<Subject> subjectDAO;

    public void setSubjectDAO(IDao<Subject> subjectDAO) {
        this.subjectDAO = subjectDAO;
    }

    @Override
    public List<Subject> getAll() throws DAOException {
        return subjectDAO.getAll();
    }

}

In my JSF bean contoller with view scope I every time getting problem with this structure.

What I should change in structure of my application?

I would make the following changes to what you have written:

SubjectServiceImpl

  • This could be singleton scoped - services don't have state.
  • You don't need a setter for subject DAO (I would use constructor injection and make the subjectDAO final.
  • Make the getAll method @Transaction (as you eluded to in your question) - this will ensure that Spring binds a Hibernate session to the thread of execution. This is then available using SessionFactory#getCurrentSession().

SubjectHibernateDAO

  • Remove code concerned with transactions eg transaction = session.beginTransaction(). The provision of a session will be handled by the @Transactional annotation on your service method.
  • Remove all rollback code
  • Make the DAO singleton scoped - again no state. It should depend on a final SessionFactory variable.
  • Inject the SessionFactory via a constructor (field injection is not great).

Once you've done all of the above you might find that your problem goes away (it's not obvious from your question what the actual problem is). The biggest problem with your code is the manual transaction mixed with the use of SessionFactory#getCurrentSession().

You haven't supplied your Spring configuration but to use @Transactional you will need to enable transactional proxying behaviour in spring. You can do this in xml using and with annotations using @EnableTransactionManagement.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM