Hibernate doesn't update record in MySQL database - java

I am using PrimeFaces 3.5, JSF 2.2, Hibernate 4.1, Spring 3.2.3, MySQL in my application.
Function updateUser() is supposed to update record in the database for the selected user from the PrimeFaces dataTable component(values are correct) but for some unknown reason it doesn't. I have a class named AbstractDAO which implements CRUD operations via generics. Insertion, selection and deleting works perfectly, but update fails without showing any errors at all. Any clues what can be wrong in my code?
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:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<!-- GLOABL SETTINGS -->
<context:component-scan base-package="com.infostroy.adminportal"/>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!-- DATA SOURCE AND PERSISTENCE SETTINGS -->
<bean id="propertiesPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:db.properties</value>
</list>
</property>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dmDataSource"/>
<property name="packagesToScan" value="com.infostroy.adminportal"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${db.dialect}</prop>
<prop key="hibernate.show_sql">${db.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${db.hbm2ddl_auto}</prop>
<prop key="connection.pool_size">${db.pool_size}</prop>
<prop key="current_session_context_class">${db.current_session_context_class}</prop>
<prop key="org.hibernate.FlushMode">${db.flush_mode}</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="dataSource" ref="dmDataSource" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="dmDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driver}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<property name="maxWait" value="5000" />
<property name="initialSize" value="2" />
<property name="maxActive" value="100"/>
<property name="maxIdle" value="50"/>
<property name="minIdle" value="0"/>
</bean>
</beans>
db.properties:
db.username=root
db.password=root
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost/adminportal
db.pool_size=0
db.dialect=org.hibernate.dialect.MySQLDialect
db.hbm2ddl_auto=validate
db.show_sql=true
db.current_session_context_class=thread
db.flush_mode=COMMIT
AbstractDAO:
public abstract class AbstractDAO<T extends Serializable> implements Serializable {
#Autowired
protected SessionFactory sessionFactory;
protected T object;
protected Class clazz;
public AbstractDAO(Class clazz) {
this.clazz = clazz;
}
//Executes before being removed from container
#PreDestroy
protected void destroy() {
sessionFactory.getCurrentSession().close();
}
public Session getHiberSession() {
return sessionFactory.openSession();
}
#Transactional
protected T getByID(int id) {
String queryString = "from " + clazz.getSimpleName() + " where id = :id";
Query query = getHiberSession().createQuery(queryString);
query.setInteger("id", id);
object = (T) query.uniqueResult();
return object;
}
#Transactional
protected int deleteByID(int id) {
String queryString = "delete " + clazz.getSimpleName() + " where id = :id";
Query query = getHiberSession().createQuery(queryString);
query.setInteger("id", id);
return query.executeUpdate();
}
#Transactional
protected boolean insert(T object) {
try {
getHiberSession().save(object);
return true;
} catch (HibernateException ex) {
return false;
}
}
#Transactional
protected boolean update(T object) {
try {
getHiberSession().saveOrUpdate(object);
return true;
} catch (HibernateException ex) {
return false;
}
}
#Transactional
protected List getAllRecords() {
String queryString = "from " + clazz.getSimpleName();
Query query = getHiberSession().createQuery(queryString);
return query.list();
}
}
UserDAO.java:
#Repository
public class UserDAO extends AbstractDAO<User> {
public UserDAO() {
super(User.class);
}
public User getUserById(int id) {
return super.getByID(id);
}
public int deleteUserById(int id) {
return super.deleteByID(id);
}
public boolean insertUser(User user) {
return super.insert(user);
}
public boolean updateUser(User user) {
return super.update(user);
}
public List<User> getAllUsers() {
return super.getAllRecords();
}
}
If you need any additional info or code - just tell me. Every answer is highly appreciated and responded immidiately.
Thank you.

I'm just starting with Hibernate, but I'm using sessionFactory.getCurrentSession() instead of openSession().

After saveOrUpdate() mehod just flush the session. Ex: session.flush();
For more details you can see my blog here:
http://www.onlinetutorialspoint.com/hibernate/hibernate-example.html

Related

Entity Manager NULL - Spring MVC JPA

In the following code the entityManager is null. What am I doing wrong? I need the entityManager to be injected automatically.
My Object Model:
#Entity
#Table(name = "jlocalidades", catalog = "7jogos")
public class Jlocalidades implements java.io.Serializable {
private Integer id;
private String nome;
private String descricao;
public Jlocalidades() {
}
public Jlocalidades(String nome, String descricao) {
this.nome = nome;
this.descricao = descricao;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "Id", unique = true, nullable = false)
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
#Column(name = "Nome", nullable = false, length = 200)
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
#Column(name = "Descricao", nullable = false, length = 200)
public String getDescricao() {
return this.descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
}
My Servlet
<?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:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<context:component-scan base-package="com.dtr.oas" />
<context:annotation-config/>
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<!-- <resources mapping="/resources/**" location="/resources/" /> -->
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="mysqlDS"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.254.38:3306/7jogos" />
<property name="username" value="root" />
<property name="password" value="6+1Log.pt" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mysqlDS"/>
<property name="persistenceProviderClass" value="org.hibernate.ejb.HibernatePersistence" />
</bean>
<tx:annotation-driven/>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
</beans>
My Persistence
<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="persistenceUnit" transaction-type="RESOURCE_LOCAL">
<!-- shouldn't be valid for java SE per specification, but it works for EclipseLink ... -->
<class>com.dtr.oas.model.Jlocalidades</class>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://192.168.254.38:3306/7jogos" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="6+1Log.pt" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
<property name="eclipselink.logging.level" value="SEVERE"/>
</properties>
</persistence-unit>
My controller that gives the ERROR
package com.dtr.oas.model;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.setelog.model.Jcelulas;
public class JlocalidadesHome implements IJlocalidadesHome {
private static final Log log = LogFactory.getLog(JlocalidadesHome.class);
#Autowired
private SessionFactory sessionFactory;
private Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
#PersistenceContext
private EntityManager entityManager;
public void persist(Jlocalidades transientInstance) {
log.debug("persisting Jlocalidades instance");
try {
EntityManager entityManager = Persistence.createEntityManagerFactory("persistenceUnit").createEntityManager();
entityManager.persist(transientInstance);
log.debug("persist successful");
} catch (RuntimeException re) {
log.error("persist failed", re);
throw re;
}
}
public void remove(Jlocalidades persistentInstance) {
log.debug("removing Jlocalidades instance");
try {
entityManager.remove(persistentInstance);
log.debug("remove successful");
} catch (RuntimeException re) {
log.error("remove failed", re);
throw re;
}
}
public Jlocalidades merge(Jlocalidades detachedInstance) {
log.debug("merging Jlocalidades instance");
try {
Jlocalidades result = entityManager.merge(detachedInstance);
log.debug("merge successful");
return result;
} catch (RuntimeException re) {
log.error("merge failed", re);
throw re;
}
}
public Jlocalidades findById(Integer id) {
log.debug("getting Jlocalidades instance with id: " + id);
try {
Jlocalidades instance = entityManager.find(Jlocalidades.class, id);
log.debug("get successful");
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
#Transactional
public List<Jlocalidades> All (){
log.debug("getting all Jlocalidades");
try {
List<Jlocalidades> instance = entityManager.createQuery("SELECT * FROM jlocalidades").getResultList();
log.debug("get successful");
return instance;
} catch (RuntimeException re) {
log.error("get failed", re);
throw re;
}
}
}
You need #Controller on your controller class in order for spring to inject the entityManager into it. Since you want Spring to inject the EntityManager, do not do:
EntityManager entityManager = Persistence.createEntityManagerFactory("persistenceUnit").createEntityManager();
Generally, you will only call Persistence.createEntityManagerFactory() when you are running without a container.
Bootstrap class that is used to obtain an EntityManagerFactory in Java
SE environments.
You can do without persistence.xml by changing your EntityManager configuration:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="mysqlDS"/>
<property name="packagesToScan" value="YOUR.ENTITY.PKG" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generatedDdl" value="true" />
<property name="databasePlatform" value="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
</bean>
</property>
</bean>
How is the controller instantiated ? Its need to be a spring managed bean.
You have classpath scanning xml defined in your conf file. But JlocalidadesHome is not annoated with Controller/Component.
By the way, use a controller to take inputs from a request, it should then call service classes ... and the service classes interact with the data layer classes

How to manage persistence using Spring and Hibernate

I just started a web application in Spring using Hibernate and this is the way I figured(after finding few ways of doing it):
GenericDAO
public interface GenericDAO<T extends DomainModel> {
public T getById(Integer id);
public List<T> getAll();
public void saveEntity(T object);
public void deleteEntity(T object);
}
GenericDAOImpl
public class GenericDAOImpl<T extends DomainModel> implements GenericDAO<T> {
private Class<T> type;
#Autowired
protected SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
public Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
public GenericDAOImpl(Class<T> type) {
super();
this.type = type;
}
#SuppressWarnings("unchecked")
#Transactional(readOnly = true)
#Override
public T getById(Integer id) {
if( id == null){
return null;
} else {
return (T) getCurrentSession().get(type, id);
}
}
#SuppressWarnings("unchecked")
#Transactional(readOnly = true)
#Override
public List<T> getAll() {
return getCurrentSession().createQuery("select o from " + type.getName() + " o").list();
}
#Transactional(readOnly = true)
#Override
public void saveEntity(T object) {
getCurrentSession().persist(object);
}
#Transactional(readOnly = true)
#Override
public void deleteEntity(T object) {
getCurrentSession().delete(object);
}
}
UserService
public interface UserService {
public void addUser(User user);
public List<User> getUsers();
public User get(Integer id);
public void delete(User user);
}
UserServiceImpl
#Service
#Transactional
public class UserServiceImpl implements UserService {
#Autowired
private GenericDAO<User> userDAO;
#Override
public void addUser(User user) {
userDAO.saveEntity(user);
}
#Override
public User get(Integer id) {
return userDAO.getById(id);
}
#Override
public void delete(User user) {
userDAO.deleteEntity(user);
}
#Override
public List<User> getUsers() {
return userDAO.getAll();
}
}
UserController
#Controller
public class UserController {
#Autowired
private UserService userService;
#RequestMapping(value = "test", method = RequestMethod.GET)
public String test(){
User u1 = userService.get(1);
return "test";
}
}
Configuration hibernate
<?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:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
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-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/online_auction" />
<property name="username" value="root" />
<property name="password" value="123456" />
</bean>
<!-- Hibernate 4 SessionFactory Bean definition -->
<bean id="mySessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="packagesToScan" value="online_auction.domain_model" />
<property name="hibernateProperties">
<props>
<!-- SQL dialect depends on which database you connect to -->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<mvc:annotation-driven/>
</beans>
Configuration Spring
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.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-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
<import resource="classpath:dataSource.xml"/>
<mvc:annotation-driven />
<context:component-scan base-package="online_auction"/>
<mvc:resources location="css" mapping="/css/**" />
<mvc:resources location="images" mapping="/images/**" />
<!-- Tiles configuration -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass">
<value>
org.springframework.web.servlet.view.tiles2.TilesView
</value>
</property>
</bean>
<bean id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles.xml</value>
</list>
</property>
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
</beans>
My questions are:
How is the management of the database connection made ? Session per
web Request ? When is the database connection opened and closed ?
Should I create the session in the Service and pass it as parameter to the repositories constructors. Should I also manipulate the session methods like : open session, begin transaction, commit, close session.
Since is my first layered application using Repository and Service any suggestions on how to manage database connection/session/transaction are more then welcomed. Thanks in advance!
A pointer for few of your queries - Consider using Spring's OpenSessionInViewInterceptor, it binds Hibernate Session to the thread for the entire processing of the request. You can have it's bean defined as:
<bean name="openSessionInViewInterceptor"
class="org.springframework.orm.hibernate4.support.OpenSessionInViewInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory" />
</property>
</bean>
and referred in "interceptors" property of SimpleUrlHandlerMapping bean in Spring's context.xml.
More detail on OpenSessionInViewInterceptor here.

Hibernate & Spring: EntityManager is Null

I'm setting up a Project with Spring and Hibernate. I created an abstract DAO class that contains an EntityManager. When I want to use this EntityManager, it's null and I dont understand why. Maybe you can help me.
My persistence-context
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<import resource="persistence-beans.xml" />
<mvc:annotation-driven />
<bean id="jdbcPropertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:META-INF/mysql.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}"
p:username="${jdbc.username}" p:password="${jdbc.password}" />
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="${hibernate.show_sql}" />
<property name="generateDdl" value="${hibernate.generate_ddl}" />
<property name="databasePlatform" value="${hibernate.dialect}" />
</bean>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="personDao" class="com.patrickzinner.dao.PersonDao" />
<tx:annotation-driven transaction-manager="transactionManager" />
PersonDao.java:
#Repository
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class PersonDao extends AbstractDao<Person> {
public PersonDao() {
super(Person.class);
}
}
AbstractDao.java
#SuppressWarnings("unchecked")
#Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public abstract class AbstractDao<T> {
#PersistenceContext
protected EntityManager em;
private Class<T> entityClass;
public AbstractDao(Class<T> entityClass) {
this.entityClass = entityClass;
}
public AbstractDao() {
}
public void create(T entity) {
this.em.persist(entity);
}
public void edit(T entity) {
this.em.merge(entity);
}
public void remove(T entity) {
this.em.remove(this.em.merge(entity));
}
public T find(long primaryKey) {
return this.em.find(entityClass, primaryKey);
}
#SuppressWarnings("rawtypes")
public List<T> findAll() {
CriteriaQuery cq = this.em.getCriteriaBuilder().createQuery();
cq.select(cq.from(entityClass));
return this.em.createQuery(cq).getResultList();
}
}
Thanks in advance!
An entity manager can only be injected in transaction classes. In other words, it can only be injected in a EJB. Other classe must use an EntityManagerFactory to create and destroy an EntityManager.
but your AbstractDAO is not EJB you can not use EntityManager directly.
solution
#PersistenceUnit(unitName = "test")
private EntityManagerFactory entityManagerFactory;
EntityManager entityManager = entityManagerFactory.createEntityManager();
then perform operation using emtityManager.
alternatively you can use container managed Transaction using JNDI lookup..
let me know for any issues.
Try adding <context:annotation-config /> to your persistence-context. This section of the reference manual may help you to use #PersistenceContext.

Getting java.lang.NullPointerException while getSession().save(entity);

I want to add object data and want to save in DB table, everything working fine but it gives me an error :
java.lang.NullPointerException
on line getSession().save(entity);
I have called this method in code :
#Service
public class AddCategoryProcessor implements ICommandProcessor<AddCategory> {
#Autowired
private IPatronCategoryRepository patronCategoryRepository = new PatronCategoryRepository();
#Override
#Transactional(propagation = Propagation.REQUIRED)
public void Process(AddCategory command){
PatronCategory entity = new PatronCategory();
entity.setCategoryName(command.getCategoryName());
try
{
patronCategoryRepository.save(entity);
}catch (Exception e){
e.printStackTrace();
}
}
}
following is my xml file :
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/abc"/>
<property name="username" value="postgres"/>
<property name="password" value="pwd"/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.ngl.domain"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.generate_statistics">true</prop>
</props>
</property>
</bean>
<!-- Transaction Manager -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
Here is a getSession() method :
#Override
public Session getSession() {
return getSessionFactory().getCurrentSession();
}
Here is a sessionFactory declaration :
protected SessionFactory sessionFactory;
Any guesses why it's NULLPOINTEREXCEPTION ??
UPDATE :
java.lang.NullPointerException
at com.ngl.commandprocessors.patroncategoryprocessor.AddCategoryProcessor.Process(AddCategoryProcessor.java:32)
at com.ngl.commandprocessors.patroncategoryprocessor.AddCategoryProcessor.Process(AddCategoryProcessor.java:16)
at com.ngl.controllerapis.BaseApiController.ProcessRequest(BaseApiController.java:29)
at com.ngl.controllerapis.PatronCategoryController.addCategory(PatronCategoryController.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
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:746)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:687)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:915)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:822)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:796)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2441)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2430)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
and xml for transaction manager
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
in repository
#Autowired
protected SessionFactory sessionFactory;
Your config is a bit incomplete. You should delegate session management completely to Spring
Add in you spring xml file:
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Then, in your PatronCategoryRepository class, extend HibernateDaoSupport and add this constructor:
public class PatronCategoryRepository extends HibernateDaoSupport implements IPatronCategoryRepository{
#Autowired
public PatronCategoryRepository(HibernateTemplate hibernateTemplate) {
super();
super.setHibernateTemplate(hibernateTemplate);
}
[...]
}
In AddCategoryProcessor, leave the definition of the repository like this:
#Autowired
private IPatronCategoryRepository patronCategoryRepository;
And finally your method:
#Override
#Transactional(propagation = Propagation.REQUIRED)
public void Process(AddCategory command){
PatronCategory entity = new PatronCategory();
entity.setCategoryName(command.getCategoryName());
try
{
getHibernateTemplate.save(entity);
}catch (Exception e){
e.printStackTrace();
}
}
In case you still need to access directy the SessionFactory, the only thing you have to do is inject it into PatronCategoryRepository:
#Repository
public class PatronCategoryRepository implements IPatronCategoryRepository{
#Autowired
protected SessionFactory sessionFactory;
public PatronCategoryRepository() {
}
public PatronCategory save(PatronCategory entity){
return getSession().save(entity);
}
private Session getSession() {
return sessionFactory.getCurrentSession();
}
}
And remember to remove the new clause from AddCategoryProcessor, leaving it like this:
#Autowired
private IPatronCategoryRepository patronCategoryRepository;
Employee.java
package com.javacodegeeks.snippets.enterprise.model;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "Employee1")
public class Employee implements Serializable {
#Id
#Column(name = "ID")
private int id;
#Column(name = "NAME")
private String name;
#Column(name = "AGE")
private int age;
public Employee() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
EmployeeDao.java
package com.javacodegeeks.snippets.enterprise.dao;
import com.javacodegeeks.snippets.enterprise.model.Employee;
public interface EmployeeDAO {
public void saveEmployee(Employee employee);
Employee findEmployeeById(int id);
void updateEmployee(Employee employee);
void deleteEmployee(Employee employee);
}
EmployeeDaoImpl.java
package com.javacodegeeks.snippets.enterprise.dao;
import java.io.Serializable;
import org.hibernate.SessionException;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.javacodegeeks.snippets.enterprise.model.Employee;
public class EmployeeDAOImpl implements EmployeeDAO {
private HibernateTemplate template;
private SessionFactory sessionFactory;
#Autowired
public void setTemplate(HibernateTemplate template) {
this.template = template;
// template.setSessionFactory(sessionFactory);
}
public void setSessionFactory(SessionFactory sessionFactory) {
new HibernateTemplate(sessionFactory);
}
/*
* public void saveEmployee(Employee employee) {
* sessionFactory.getCurrentSession().save(employee);
*
* }
*/
public Employee findEmployeeById(int id) {
return (Employee) sessionFactory.getCurrentSession().get(
Employee.class, id);
}
public void updateEmployee(Employee employee) {
sessionFactory.getCurrentSession().update(employee);
}
public void deleteEmployee(Employee employee) {
sessionFactory.getCurrentSession().delete(employee);
}
public void saveEmployee(Employee employee) {
sessionFactory.getCurrentSession().persist(employee);
template.saveOrUpdate(employee);
}
}
Application COntext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
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:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
<context:component-scan base-package="com.javacodegeeks.snippets.enterprise.*" />
<!-- <tx:annotation-driven/> -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="annotatedClasses">
<list>
<value>com.javacodegeeks.snippets.enterprise.model.Employee</value>
</list>
</property>
<!-- <property name="mappingResources">
<list>
<value>Employee.hbm.xml</value>
</list>
</property> -->
<property name="hibernateProperties">
<props>
<prop
key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean> -->
<bean id="template" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="d" class="com.javacodegeeks.snippets.enterprise.dao.EmployeeDAOImpl">
<property name="template" ref="template"></property>
</bean>
</beans>
pleas ehelp me :-)

What is a solution develop correctly this Spring and JPA webapp example?

I have a Controller for my webapp developed with Spring mvc under Maven 3. In this controller I've #Autowired
PersonDAO dbController
I want to use JPA 2.0 to manage persistance so I rewrited my applicationContext.xml:
I added
`<tx:annotation-driven transaction-manager="transactionManager" />
<bean
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
id="entityManagerFactory">
<property name="dataSource" ref="dataSource" />
<!-- <property name="packagesToScan" value="net.tirasa.test.addressbook.dao" />-->
<property name="persistenceUnitName" value="persistenceUnit" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<!--<property name="generateDdl" value="true" />-->
<!--<property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />-->
<!--<property name="database" value="H2" />-->
</bean>
</property>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager"
id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>`
and my PersonDAOImpl is:
#Repository
public class PersonDAOJpaImpl implements PersonDAO {
//#Value("#{entityManager}")
#PersistenceContext(type = PersistenceContextType.TRANSACTION)
//#Autowired
protected EntityManager entityManager;
private final static Logger LOG = LoggerFactory.getLogger(PersonDAOJpaImpl.class);
#Transactional
public void save(String id, String name, String email, String telephone) throws DatabaseException {
Person person = null;
if (find(id) == null) {
entityManager.persist(person);
} else {
entityManager.merge(person);
}
}
#Transactional
public Person find(String requestParam_id) throws DatabaseException {
return entityManager.find(Person.class, requestParam_id);
}
#Transactional
public List<Person> list() throws DatabaseException {
Query query = entityManager.createQuery("select p from Persons p");
List<Person> resultList = query.getResultList();
Person p = null;
entityManager.find(Person.class, "Andrea Patricelli");
System.out.println("ECCO UN ELEMENTO DELLA LISTA: ------->" + resultList.iterator().next().getName());
System.out.println("ECCO IL RISULTATO DELLA FIND: -------->" + p.getName());
return resultList;
}
but nothing works;
what do I do wrong?
In particular I don't know how to connect My PersonDAO dbController with PersonDAOImpl and with entityManager
To start off your packages to scan is not setup correctly for the entityManagerFactory. You are scanning your dao's there when you should be scanning your model/domain(Classes with #Entity on them).

Categories