Reputation: 1232
I have started learning hibernate and spring through an assignment in which i am trying to use session factory instance through spring. I understood the hibernate part but just cant go on with spring. I have tried numerous tutorials and examples but just cant get my spring working. Although it works when i instantiate it directly. Here are the problem related details of my project...
applicationContext.xml (inside WEB-INF)
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config />
<context:component-scan
base-package="com.nagarro.training.assignment6.dao.entity.Student" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation" value="classpath:hibernate.cfg.xml"></property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.HSQLDialect
</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven />
<bean id="studentDAO"
class="com.nagarro.training.assignment6.dao.impl.StudentDAOImplementation">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
Edit: including changes as suggested StudentDAOImplementaion.java (the file where it is being used )
public class StudentDAOImplementation implements StudentDAO {
/**
* single instance of hibernate session
*/
@Autowired
private SessionFactory sessionFactory;
// HibernateUtil.getSessionFactory().openSession()
/**
* @param sessionFactory
*/
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/**
* @return the sessionFactory
*/
public SessionFactory getSessionFactory() {
return sessionFactory;
}
private Session getSession() {
return this.sessionFactory.getCurrentSession();
}
/**
* @return list of all the students
*/
public List<Student> getStudentList() {
System.out.println(this.getSession().getStatistics());
return (List<Student>) this.getSEssion.createQuery("from Student")
.list();
}
}
And here is the snip of my jar files in lib folder:
I think that i dont need to include hibernate files and beans as it is working fine without spring. Its the spring i cant get to work.I have tried many different implementation from the web but i just cannot get it working. It just says null pointer exception on ** System.out.println(sessionFactory.getStatistics());** line in StudentDAOImplementation.
Test class that calls StudentDAO
public class Test {
public static void main(String[] args) {
StudentDAOImplementation sd = new StudentDAOImplementation();
List<Student> list = sd.getStudentList();
for(Student s : list) {
System.out.println(s.getName());
}
}
}
Stack trace
Exception in thread "main" java.lang.NullPointerException
at StudentDAOImplementation.getStudentList(StudentDAOImplementation.java:116)
at Test.main(Test.java:13)
Upvotes: 2
Views: 5006
Reputation: 128779
Your sessionFactory
variable is misleadingly named, since the type is actually Session
. Session
!= SessionFactory
. You're getting a NPE on sessionFactory.getStatistics()
because there's no way that Spring can autowire a Session into a DAO like that. If you're not seeing an error before the NPE, then you're not actually instantiating the DAO with Spring, or else you'd get an error about not being able to find a dependency of type Session. The appropriate way to use a Hibernate-based DAO is to inject it with a SessionFactory
and call getCurrentSession()
in your methods where you need a Session
. See "Implementing DAOs based on plain Hibernate 3 API" and following for details about this approach and about setting up appropriate transaction management.
Update: On a second glance, I see that the package for your component-scan is set to com.nagarro.training.assignment6.dao.entity.Student
, which looks exactly like a class, not a package. It's also not even close to anything you'd actually want to component-scan. Maybe you don't understand what component-scan is for. It's covered under "Annotation-based container configuration" in the reference guide.
Update 2: About your "test" code: you're not using Spring at all, so you might as well remove the XML and save yourself the trouble. On the other hand, if you'd like to actually use Spring, you'd need to create a context in your main method based on said XML file, such as:
ApplicationContext context = new FileSystemXmlApplicationContext(locationOfXmlFile);
Then if you want a Spring-managed DAO, you can't just create one with new
. Spring isn't magic. It doesn't grab control away from you just because you have it loaded somewhere in the same JVM.* You have to ask Spring for the DAO that it created, like:
StudentDAO dao = context.getBean(StudentDAO.class);
Note that I used the interface type, not the concrete type. That's always an advisable practice for numerous reasons.
This (not starting Spring) is your first problem. As soon as you do this, you're going to run into other problems with your configuration. You should post a new question if you need help solving one of them.
*Unless you're using AspectJ weaving to inject arbitrary objects.
Upvotes: 2
Reputation: 5739
You are injecting a Session
instead of SessionFactory
with @Autowired private Session sessionFactory;
in the DAO class. It needs to be a SessionFactory
, like this
@Autowired SessionFactory sessionFactory;
And then use it like this to do a DAO operations like save
Session session = sessionFactory.getCurrentSession()
session.persist(entity);
EDIT
Your testcase should be something like this
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:<path_to_your_appcontext.xml>" })
public class StudentDAOTest {
@Autowired
private StudentDAO studentDAO
@Test
public void test() {
List<Student> list = studentDAO.getStudentList();
assertNotNull(list)
}
}
Upvotes: 1