Issue
I am trying to learn creating ReST API end points using spring mvc and Hibernate without using springboot. When I am running my end point , I am getting internal server error saying that ,
java.lang.NullPointerException: Cannot invoke "javax.persistence.EntityManager.createQuery(String, java.lang.Class)" because "this.entityManager" is null
.
My spring-servlet.xml file under src/main/webapp/web-1nf is like the following,
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<annotation-driven />
<resources mapping="/resources/**" location="/resources/" />
<beans:bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="org.postgresql.Driver" />
<beans:property name="url" value="jdbc:postgresql://localhost:5432/company" />
<beans:property name="username" value="postgres" />
<beans:property name="password" value="postgresql" />
<!--<property name="socketTimeout" value="10"/>-->
<beans:property name="connectionProperties">
<beans:props>
<beans:prop key="socketTimeout">10</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.springmvc.Employee</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop
key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<context:component-scan base-package="com.springmvc" />
<tx:annotation-driven transaction-manager="transactionMgr"/>
<beans:bean id="transactionMgr"
class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="entityManagerFactory" ref="mgrFactory"/>
</beans:bean>
<beans:bean id="mgrFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource"/>
<beans:property name="packagesToScan" value="com.springmvc"/>
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</beans:property>
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</beans:prop>
<beans:prop key="hibernate.dialect">${hibernate.dialect}</beans:prop>
<beans:prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</beans:prop>
<beans:prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</beans:prop>
<beans:prop key="hibernate.show_sql">${hibernate.show_sql}</beans:prop>
<beans:prop key="hibernate.format_sql">${hibernate.format_sql}</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
</beans:beans>
My controller is ,
@RestController
@RequestMapping("/mvchibernate")
public class CompanyController {
@Autowired
EmployeeService employeeService;
@GetMapping(value = "/getAllEmployees")
public List<Employee> getEmployeesList() {
@SuppressWarnings("unchecked")
List<Employee> listOfEmployees = employeeService.getAllEmployees();
return listOfEmployees;
}
}
And my service class like the following,
@Service
public class EmployeeService {
@Autowired
EmployeeDAO employeeDaoObj;
public List getAllEmployees() {
return employeeDaoObj.getAllEmployees();
}
}
And DAO implementation ,
@Repository
public class EmployeeDAO {
@PersistenceContext private EntityManager entityManager;
public List<Employee> getAllEmployees() {
String jpql = "SELECT e FROM Employee e";
TypedQuery<Employee> query = entityManager.createQuery(jpql, Employee.class);
return query.getResultList();
}
}
Here in my DAO class I autowired the entitymanager.And while running I am getting Cannot invoke javax.persistence.EntityManager
and last showing that because "this.entityManager" is null
.
So can anyone guide me to resolve this issue or kindly refer any documentation to follow please?
Solution
Edit from my previous answer, After reviewing your code below is what you are currently doing:
You created
PersistenceConfig.java
withConfiguration
annotation. This class is empty & it looks you have commented it after creating & defining beans.Spring is actually checking
PersistenceConfig.java
for finding configurations instead of going to your xml.Move your xml config to
src/main/resources
& for supporting best practice rename it topersistence.xml
.Now, you have to tell spring to read your configs from
persistence.xml
instead of looking anywhere else. Comment outConfiguration
annotation fromPersistenceConfig.java
& use below annotation in your main class :
:
@SpringBootApplication
@ImportResource({ "classpath:persistence.xml" })
public class SpringMvcHibernateRestApiApplication {
public static void main(String[] args) {
SpringApplication.run(SpringMvcHibernateRestApiApplication.class, args);
}
}
- Also, I suggest to use
org.springframework.orm.hibernate5.LocalSessionFactoryBean
instead oforg.springframework.orm.hibernate4.LocalSessionFactoryBean
as it will be inline with your latest spring & jpa versions. Once you used this, you will be able to see entitymanager got created properly.
Edit : As per OP's comment, point number 5 is not required on their machine.
Answered By - Ashish Patil
Answer Checked By - Terry (JavaFixing Volunteer)