Spring: BeanCreationException
Solution 1
Use the @PostConstruct
tag and get the session then. Your beans will only be injected after your UserDaoImpl
is created and @PostConstruct
method will only be called by Spring after all your beans are injected.
@Service
public class UserDaoImpl implements UserDao {
@Autowired
private SessionFactory sessionFactory;
private Session session;
public UserDaoImpl() {
}
@PostConstruct
public void init() {
this.session = sessionFactory.getCurrentSession();
}
...
}
Another way (better in my opnion) is inject by constructor and getting the current session only when you need it.
...
private final SessionFactory sessionFactory;
@Autowired
public UserDaoImpl(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
private Session currentSession() {
return this.sessionFactory.getCurrentSession();
}
EDIT:
Use the second way preferably, because if you get the session only after construct, calls to your DAO won't work once that session is expired. Always use SessionFactory#getCurrentSession()
when starting make calls at your transactional methods.
Solution 2
As Ralf points out, the constructor is executed too early and Spring did not inject anything at this point.
Further, you may not hold a reference to Session as it relies on the SessionContext mechanism, which in turn may be thread bound or servlet request bound. Your bean may has a wider scope (e.g. singleton) and you will permanently store the session from the first caller or something!
I suggest to always get the session from sessionFactory when needed inside the bean.
Mr. Polywhirl
Languages (Ordered by proficiency): Server: java, c++, python, c#* Web: javascript, actionscript, php, perl DB: mysql, mongodb Other: pascal, mips64, lisp* Markup: html, markdown, mxml, xml
Updated on June 04, 2022Comments
-
Mr. Polywhirl almost 2 years
I am trying to get the session from the session factory to use with my CRUD methods. I tried to set the session in the constructor, but the bean has not been initialized by then. How do I initialize it after the bean is created?
Stacktrace
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDaoImpl' defined in file [/home/ryan/workspace/com-byteslounge-spring-tx/target/classes/com/byteslounge/spring/tx/dao/impl/UserDaoImpl.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.byteslounge.spring.tx.dao.impl.UserDaoImpl]: Constructor threw exception; nested exception is java.lang.NullPointerException at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1011) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:957) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139) at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83) at com.byteslounge.spring.tx.Main.main(Main.java:19) Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.byteslounge.spring.tx.dao.impl.UserDaoImpl]: Constructor threw exception; nested exception is java.lang.NullPointerException at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163) at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1004) ... 13 more Caused by: java.lang.NullPointerException at com.byteslounge.spring.tx.dao.impl.UserDaoImpl.<init>(UserDaoImpl.java:24) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:525) at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148) ... 15 more
UserDaoImpl.java
package com.byteslounge.spring.tx.dao.impl; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.byteslounge.spring.tx.dao.UserDao; import com.byteslounge.spring.tx.domain.User; @Service public class UserDaoImpl implements UserDao { @Autowired private SessionFactory sessionFactory; private Session session; public UserDaoImpl() { session = sessionFactory.getCurrentSession(); } public SessionFactory getSessionFactory() { return this.sessionFactory; } public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } public void insertUser(User user) { session.save(user); } public void removeUserByName(String username) { User user = null; try { getUser(username); } catch (IndexOutOfBoundsException e) { System.out.println(username + " does not exist!"); } finally { if (user != null) session.delete(user); } } public User getUserById(int userId) { return (User) session.get(User.class, userId); } public User getUser(String username) { // Query query = sessionFactory.getCurrentSession().createQuery("from User where username = :username"); // query.setParameter("username", username); Query query = session.getNamedQuery(User.FIND_USER_BY_USERNAME).setString("username", username); return (User) query.list().get(0); } @SuppressWarnings("unchecked") public List<User> getUsers() { Criteria criteria = session.createCriteria(User.class); return criteria.list(); } }
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" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <tx:annotation-driven /> <context:component-scan base-package="com.byteslounge.spring.tx.dao.impl" /> <context:component-scan base-package="com.byteslounge.spring.tx.user.impl" /> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location"> <value>database.properties</value> </property> </bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">true</prop> </props> </property> <property name="packagesToScan" value="com.byteslounge.spring.tx.domain" /> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager" p:sessionFactory-ref="sessionFactory"> </bean> </beans>
-
Caesar Ralf almost 11 years@Mr.Polywhirl mark as an answer then, please :) glad I could help
-
Mr. Polywhirl almost 11 yearsSorry, I was working on something else. I had to wait to accept.