Spring EntityManager not persisting in standalone application - spring

I'm having problems getting my EntityManager to persist my #Entity object in my standalone application. There are no errors, but nothing is persisted into the HSQL database.
I'm sure it must be something silly but i'm at my wits end with it now. I've searched and searched and tried everything but i still can't get it to work.
appconfig.xml:
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" />
<bean id="productDaoImpl" class="test.ProductDao"/>
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:component-scan base-package="test">
</context:component-scan>
persistence.xml:
<persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.username" value=""/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.connection.url" value="jdbc:hsqldb:file://c:/db2"/>
</properties>
</persistence-unit>
</persistence>
EntityObj.java:
package test;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
#Entity
public class EntityObj {
#Id
#GeneratedValue
private int id;
private String value;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
ProductDao.java:
package test;
import org.springframework.dao.DataAccessException;
public interface ProductDao {
public void save(EntityObj obj) throws DataAccessException;
}
ProductDaoImpl.java:
package test;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Transactional
public class ProductDaoImpl implements ProductDao {
#PersistenceContext
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
#Transactional (readOnly = false)
public void save(EntityObj obj)
{
try
{
entityManager.persist(obj);
entityManager.flush();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
Main.java:
package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Main {
public static void main(String[] args)
{
ApplicationContext springContext = new FileSystemXmlApplicationContext("classpath*:appconfig.xml");
ProductDao dao = (ProductDao) springContext.getBean("productDaoImpl");
EntityObj obj = new EntityObj();
obj.setValue("Blah");
dao.save(obj);
}
}
There are no errors whatsoever, it appears like it has saved the EntityObj but nothing is persisted in the database. I get the feeling it is transaction related and probably due to how i am instantiating the objects but i'm not sure.
The ENTITYOBJ database table is created automatically, just no data.

Related

autowired dao NullPointerException spring mvc + hibernate [duplicate]

This question already has answers here:
Why is my Spring #Autowired field null?
(21 answers)
Closed 7 years ago.
I'm trying to learn Spring MVC and Hibernate. When I try to run tests I have "Exception in thread "main" java.lang.NullPointerException".
public interface VacancyDAO
package pro.asfert.jobparser.dao;
public interface VacancyDAO {
void LoadDataBase(String query);
void FindVacancy(String queries);}
public class VacancyDAOImpl
package pro.asfert.jobparser.dao;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
#Repository
public class VacancyDAOImpl implements VacancyDAO {
#Autowired
private SessionFactory sessionFactory;
public void LoadDataBase(String query) {
sessionFactory.getCurrentSession().createQuery(query);
}
public void FindVacancy(String queries) {
if (queries.contains("По вашему запросу: ")) {
System.out.print(queries);
} else {
sessionFactory.getCurrentSession().createQuery(queries);
}
}
}
public interface VacancyService
package pro.asfert.jobparser.service;
public interface VacancyService {
void LoadDataBase();
void FindVacancy(String queries);
}
**public class VacancyServiceImpl**
package pro.asfert.jobparser.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pro.asfert.jobparser.dao.VacancyDAO;
import pro.asfert.jobparser.domain.Parser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
#Service
public class VacancyServiceImpl implements VacancyService {
#Autowired
private VacancyDAO VacancyDAO;
public static void main(String[] args) {
VacancyServiceImpl vacancyService = new VacancyServiceImpl();
vacancyService.FindVacancy("test");
}
/* deleted */
#Transactional
public void LoadDataBase() {
VacancyDAO.LoadDataBase(query);
}
#Transactional
public void FindVacancy(String queries) {
VacancyDAO.FindVacancy(sqlQuery);
}
application-context.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"
xsi:schemaLocation="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.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd ">
<context:annotation-config />
<context:property-placeholder location="classpath:jdbc.properties" system-properties-mode="ENVIRONMENT"/>
<context:component-scan base-package="pro.asfert.jobparser.dao"/>
<context:component-scan base-package="pro.asfert.jobparser.service"/>
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory">
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value = "${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.databaseurl}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id = "sessionFactory" class = "org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref = "dataSource"/>
<property name="configLocation" value="classpath:hibernate.cfg.xml"/>
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.connection.charSet">UTF-8</prop>
</props>
</property>
</bean>
</beans>
hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class = "pro.asfert.jobparser.domain.Vacancy"></mapping>
</session-factory>
</hibernate-configuration>
Vacancy
package pro.asfert.jobparser.domain;
import javax.persistence.*;
#Entity
#Table(name = "Vacancies")
public class Vacancy {
public Vacancy() {
}
#Id
#Column(name = "id")
#GeneratedValue
private Integer id;
#Column (name = "vacancy")
private String vacancy;
#Column (name = "salary")
private String salary;
#Column (name = "experience")
private String experience;
#Column (name = "education")
private String education;
#Column (name = "employer")
private String employer;
#Column (name = "details")
private String details;
#Column (name = "hr")
private String hr;
#Column (name = "url")
private String url;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getVacancy() {
return vacancy;
}
public void setVacancy(String vacancy) {
this.vacancy = vacancy;
}
public String getSalary() {
return salary;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getExperience() {
return experience;
}
public void setExperience(String experience) {
this.experience = experience;
}
public String getEducation() {
return education;
}
public void setEducation(String education) {
this.education = education;
}
public String getEmployer() {
return employer;
}
public void setEmployer(String employer) {
this.employer = employer;
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
public String getHr() {
return hr;
}
public void setHr(String hr) {
this.hr = hr;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
You're creating the service with new here:
public static void main(String[] args) {
VacancyServiceImpl vacancyService = new VacancyServiceImpl();
vacancyService.FindVacancy("test");
}
That way Spring is not involved and does not know anything about this object.
How to fix it:
register your dao and service as spring beans.
initialize the context and get the service from the context and call your method.
ApplicationContext ctx = new ClassPathXmlApplicationContext("application-context.xml");
VacancyServiceImpl serv = ctx.getBean(VacancyServiceImpl.class);
serv.FindVacancy("test");

No Session found for current thread] when invoke Service method

I try invoke my method which return admin lists, but when I invoke this method i get the error no session found.
roo-context.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!-- Root Context: defines shared resources visible to all other web components -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:#localhost:1521:XE" />
<property name="username" value="HR" />
<property name="password" value="asdfghj" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="pl.piotr.ibank.model" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
org.hibernate.dialect.Oracle10gDialect
</prop>
<prop key="hibernate.show_sql">
true
</prop>
</props>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="myAuthenticationSuccessHandler" class="pl.piotr.ibank.security.MyAuthenticationSuccessHandler" />
</beans>
servlet-context:
<?xml version="1.0" encoding="UTF-8"?>
<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"
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">
<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->
<context:component-scan base-package="pl.piotr.ibank" />
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- 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 -->
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
</beans:beans>
UserServiceImpl:
package pl.piotr.ibank.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pl.piotr.ibank.daointerface.UserDao;
import pl.piotr.ibank.model.User;
import pl.piotr.ibank.serviceinterface.UserService;
#Service
#Transactional
public class UserServiceImpl implements UserService {
#Autowired
UserDao userDao;
#Override
public void createUser(User user) {
userDao.createUser(user);
}
#Override
public void updateUser(User user) {
userDao.updateUser(user);
}
#Override
public void deleteUser(int id) {
userDao.deleteUser(id);
}
#Override
public User getUser(int id) {
return userDao.getUser(id);
}
#SuppressWarnings("rawtypes")
#Override
public List getAdminList() {
return userDao.getAdminList();
}
#Override
public User findByUsername(String username) {
return userDao.findByUsername(username);
}
}
UserService interface:
package pl.piotr.ibank.serviceinterface;
import java.util.List;
import pl.piotr.ibank.model.User;
public interface UserService {
void createUser(User user);
void updateUser(User user);
void deleteUser(int id);
User getUser(int id);
#SuppressWarnings("rawtypes")
List getAdminList();
User findByUsername(String username);
}
UserDaoImpl
package pl.piotr.ibank.dao;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import pl.piotr.ibank.daointerface.UserDao;
import pl.piotr.ibank.model.User;
#Repository
public class UserDaoImpl implements UserDao {
#Autowired
private SessionFactory sessionFactory;
#Override
public void createUser(User user) {
getCurrentSession().save(user);
}
#Override
public void updateUser(User user) {
getCurrentSession().update(user);
}
#Override
public void deleteUser(int id) {
User user = getUser(id);
if (user != null) {
getCurrentSession().delete(user);
}
}
#Override
public User getUser(int id) {
User user = (User) getCurrentSession().get(User.class, id);
return user;
}
#SuppressWarnings("rawtypes")
#Override
public List getAdminList() {
return getCurrentSession()
.createQuery(
"from User u, UserRole ur where u.id = ur.user.id and ur.user = 'ROLE_ADMIN'")
.list();
}
#SuppressWarnings("unchecked")
#Override
public User findByUsername(String username) {
List<User> users = new ArrayList<User>();
System.out.println(username);
try {
users = getCurrentSession()
.createQuery("from User where username=:username")
.setParameter("username", username).list();
System.out.println("Liczba " + users.size());
} catch (Exception e) {
System.out.println(e.getMessage());
}
if (users.size() > 0) {
return users.get(0);
} else {
return null;
}
}
private Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
UserDao interface:
package pl.piotr.ibank.daointerface;
import java.util.List;
import pl.piotr.ibank.model.User;
public interface UserDao {
void createUser(User user);
void updateUser(User user);
void deleteUser(int id);
User getUser(int it);
#SuppressWarnings("rawtypes")
List getAdminList();
User findByUsername(String username);
}
Controller which invoke getAdminList:
package pl.piotr.ibank.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import pl.piotr.ibank.model.User;
import pl.piotr.ibank.serviceinterface.UserService;
#Controller
public class AdminController {
#Autowired
private UserService userService;
#SuppressWarnings("unchecked")
#RequestMapping(value = "/admin/adminlist", method = RequestMethod.GET)
public ModelAndView goAdminList() {
ModelAndView mav = new ModelAndView("admin/adminlist");
List<User> admins = userService.getAdminList();
mav.addObject("admins", admins);
return mav;
}
}
Login method work good, loadbyusername, but when i invoke method service.getAdminList() i have this error:
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/ibank] threw exception [Request processing failed; nested exception is org.hibernate.HibernateException: No Session found for current thread] with root cause
org.hibernate.HibernateException: No Session found for current thread
I find that in your code you auto wire 'Sessionfactory' in your DAO implement, which means that you needs to handle session manually, including open session and close session when necessary. Since you are using Spring and hibernate, I suggest to use Template like HiberateTemplate, which Spring will take care of session for you. Every time you want to use session, just call 'getCurrentSession()', like what you are doing in you code.
Try to make a abstract DAO class that extends HibernateDaoSupport, like
public abstract class BasicDAO extends HibernateDaoSupport{
......
}
For your DAO implement, extends this class, and you code would work fine.

Spring service layer object comes null

Hi I am learning Spring and has stuck to a problem.
I have a structure something like the following:
package com.edfx.model;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name = "CUSTOMER")
public class Customer {
private long customer_id;
private String name;
private String address;
private Date created_date;
#Id
#Column(name = "CUSTOMER_ID")
public long getCustomer_id() {
return customer_id;
}
public void setCustomer_id(long customer_id) {
this.customer_id = customer_id;
}
#Column(name = "NAME")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Column(name = "ADDRESS")
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
#Column(name = "CREATED_DATE")
public Date getCreated_date() {
return created_date;
}
public void setCreated_date(Date created_date) {
this.created_date = created_date;
}
#Override
public String toString(){
StringBuffer strBuffer = new StringBuffer();
strBuffer.append("customer_id:").append(getCustomer_id());
strBuffer.append(", name : ").append(getName());
strBuffer.append(", address: ").append(getAddress());
strBuffer.append(", created_date: ").append(getCreated_date());
return strBuffer.toString();
}
}
The Managed Bean is:
package com.edfx.managedbean;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import org.springframework.dao.DataAccessException;
import com.edfx.customer.service.ICustomerService;
import com.edfx.model.Customer;
#ManagedBean(name = "customerMB")
#SessionScoped
public class CustomerManagedBean implements Serializable {
/**
*
*/
private static final long serialVersionUID = 8839370045113377019L;
private static final String SUCCESS = "success";
private static final String ERROR = "error";
// Spring Customer Service Injection
ICustomerService customerService;
public ICustomerService getCustomerService() {
System.out.println("customerService -- >"+customerService);
return customerService;
}
public void setCustomerService(ICustomerService customerService) {
this.customerService = customerService;
}
List<Customer> userList;
private long customer_id;
private String name;
private String address;
private Date created_date;
public String addUser(){
System.out.println("Managed Bean Add User..");
try {
Customer customer = new Customer();
System.out.println("ID :: "+getCustomer_id());
customer.setCustomer_id(getCustomer_id());
System.out.println("Name :: "+getName());
customer.setName(getName());
System.out.println("Address :: "+getAddress());
customer.setAddress(getAddress());
System.out.println("Created Date :: "+new Date());
customer.setCreated_date(new Date());
//Service Provider
getCustomerService().addUser(customer);
return SUCCESS;
} catch (DataAccessException e) {
System.err.println("Error Occured :: "+e.getMessage());
}
return ERROR;
}
public void reset(){
this.setCustomer_id(0);
this.setName("");
this.setAddress("");
this.setCreated_date(null);
}
public List<Customer> getUserList(){
userList = new ArrayList<Customer>();
System.out.println("BEAN :: "+getCustomerService().getUsers());
userList.addAll(getCustomerService().getUsers());
return userList;
}
public void setUserList(List<Customer> userList) {
this.userList = userList;
}
public long getCustomer_id() {
return customer_id;
}
public void setCustomer_id(long customer_id) {
this.customer_id = customer_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Date getCreated_date() {
return created_date;
}
public void setCreated_date(Date created_date) {
this.created_date = created_date;
}
}
The applicationContextFile is:
<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:aop="http://www.springframework.org/schema/aop"
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-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/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="com.edfx.managedbean"/>
<context:annotation-config/>
<!-- Bean Declaration -->
<bean id="Customer" class="com.edfx.model.Customer"/>
<!-- Customer Service Declaration -->
<bean id="customerService" class="com.edfx.customer.service.CustomerService" scope="prototype">
<property name="customerDAO" ref="CustomerDAO"/>
</bean>
<!-- Customer DAO Declaration -->
<bean id="CustomerDAO" class="com.edfx.customer.dao.CustomerDAO">
<property name="sessionFactory" ref="SessionFactory"/>
</bean>
<!-- Data Source Declaration -->
<bean id="DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/mydatabase"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
<property name="maxPoolSize" value="10"/>
<property name="maxStatements" value="0"/>
<property name="minPoolSize" value="5"/>
</bean>
<!-- Session Factory Declaration -->
<bean id="SessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="DataSource"/>
<property name="annotatedClasses">
<list>
<value>com.edfx.model.Customer</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>
<!-- Enable the configuration of transactional behaviour based on annotation -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Transaction Manager is defined -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="SessionFactory"/>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="runMeJob"/>
</list>
</property>
<property name="triggers">
<list>
<ref bean="cronTrigger"/>
</list>
</property>
</bean>
<!-- Spring Configuration Manager -->
<bean id="runMeTask" class="com.edfx.customer.schedular.RunMeTask"/>
<!-- Spring Quartz -->
<bean name="runMeJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.edfx.customer.schedular.RunMeJob"/>
<property name="jobDataAsMap">
<map>
<entry key="runMeTask" value-ref="runMeTask"/>
</map>
</property>
</bean>
<!-- Simple Trigger every 5 secs
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
<property name="jobDetail" ref="runMeJob"/>
<property name="repeatInterval" value="5000"/>
<property name="stratDelay" value="1000"/>
</bean> -->
<!-- CronTrigger runs every 5 secs-->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="runMeJob"/>
<property name="misfireInstructionName" value="MISFIRE_INSTRUCTION_FIRE_ONCE_NOW" />
<property name="cronExpression" value="0 30 19 * * ?"/>
</bean>
Here I have set a schedular. The scheduler works absolutely fine as it fires properly at the specific time.
Here is the Job details that is scheduled to run:
package com.edfx.customer.schedular;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.naming.directory.Attributes;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.web.context.ContextLoader;
import com.edfx.customer.ldap.mngr.LDAPManager;
import com.edfx.customer.service.CustomerService;
import com.edfx.customer.service.ICustomerLdapSyncService;
import com.edfx.customer.service.ICustomerService;
import com.edfx.managedbean.CustomerManagedBean;
import com.edfx.model.Customer;
public class RunMeJob extends QuartzJobBean{
private RunMeTask runMeTask;
#Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
ApplicationContext applicationContext = null;
try {
applicationContext = (ApplicationContext)context.getScheduler().getContext().get("applicationContext");
} catch (Exception e) {
System.err.println("Synchronization Error :: "+e.getMessage());
}
if(applicationContext == null)
applicationContext = ContextLoader.getCurrentWebApplicationContext();
System.out.println("=============== SCHEDULAR SERVICE ON =================");
System.out.println("MAP DETAILS == >"+new LDAPManager().getUserDetails());
Map<String, String> userDetailsMap = new LDAPManager().getUserDetails();
CustomerManagedBean customerManagedBean = new CustomerManagedBean();
int i=0;
for(Map.Entry<String, String> entry : userDetailsMap.entrySet()){
i++;
String key = entry.getKey();
String value = entry.getValue();
System.out.println("Key -->"+key+" :: Value-->"+value);
customerManagedBean.setCustomer_id(i);
customerManagedBean.setName(key);
customerManagedBean.setAddress(value);
customerManagedBean.setCreated_date(new Date());
}
customerManagedBean.addUser();
runMeTask.printMe();
System.out.println("=============== SCHEDULAR SERVICE OFF ================");
}
public void setRunMeTask(RunMeTask runMeTask) {
this.runMeTask = runMeTask;
}
}
Here, the method addUser() invokes properly. But while executing getCustomerService().addUser(customer); it throws NullPointerException as it gets customerService object null, which has been injected in the CustomerManagedBean class. mentioned in applicationContext.xml.
What could be the possible reason for this?
Please Help!
First problem I found is that, in your executeInternal method you are not using customerManagedBean from your Spring application context. Instead of that, you are creating one like bellow:
CustomerManagedBean customerManagedBean = new CustomerManagedBean();
And when you are creating your own bean, its your responsibility to prepare it before use (injection or initialization), because you are not using it from any context made and managed by any framework (Spring or something else). You could avoid these problems by simply getting the bean from Spring's ApplicationContext, by replacing the above line with the line bellow:
CustomerManagedBean customerManagedBean = (CustomerManagedBean)applicationContext.getBean("beanName")
Second thing,
Are you using JSF with Spring?
If your answer is no, then why you are using JSF annotations (#ManagedBean and #SessionScoped). As these annotations are not recognizable to Spring. Spring actually doesn't instantiate it in its context. Although you putted,
<context:component-scan base-package="com.edfx.managedbean"/>
in your applicationContext.xml.
If your answer is yes, then you should follow, the following tutorials properly to configure successfully:
jsf 2.0 spring integration example
jsf 2.0 spring hibernate integration example

Spring + Hibernate id issue while saving object with one-to-many mapping

I'm having a problem with Hibernate 4 and Spring 3. I'm also using BoneCP. I'm trying to save an Article with many Images, and that works well. However, when I try to get the ID of any Image it returns 0. In the database, however, everything is saved fine. I guess the problem lays somewhere within relation persisting or my understanding of Hibernate as after execution the id is valid, but I can't find it.
My files:
spring-hibernate.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
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/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" autowire="autodetect">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.smiechmateusz.model.Article</value>
<value>com.smiechmateusz.model.Image</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy">
<property name="targetDataSource">
<ref local="mainDataSource" />
</property>
</bean>
<bean id="mainDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/java" />
<property name="username" value="root"/>
<property name="password" value="toor"/>
<property name="idleConnectionTestPeriod" value="60"/>
<property name="idleMaxAge" value="240"/>
<property name="maxConnectionsPerPartition" value="60"/>
<property name="minConnectionsPerPartition" value="20"/>
<property name="partitionCount" value="3"/>
<property name="acquireIncrement" value="10"/>
<property name="statementsCacheSize" value="50"/>
<property name="releaseHelperThreads" value="3"/>
</bean>
<bean id="txManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
<context:annotation-config />
<context:component-scan base-package="com.smiechmateusz.dao" />
<bean id="hibernateConfiguration" factory-bean="&sessionFactory" factory-method="getConfiguration" />
<bean id="AbstractHibernateDAO" abstract="true"
class="com.smiechmateusz.dao.AbstractDAO">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="ImageDAO" parent="AbstractHibernateDAO" class="com.smiechmateusz.dao.ImageDAO" />
<bean id="ArticleDAO" parent="AbstractHibernateDAO" class="com.smiechmateusz.dao.ArticleDAO" />
</beans>
AbstractDAO.java
package com.smiechmateusz.dao;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.PersistentObjectException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Repository
#Transactional()
public abstract class AbstractDAO<T extends Serializable>
{
private final Class<T> clazz;
#Autowired
SessionFactory sessionFactory;
public AbstractDAO(final Class< T> clazzToSet)
{
this.clazz = clazzToSet;
}
public T getById(final Long id)
{
if (id != null)
return (T) this.getCurrentSession().get(this.clazz, id);
return null;
}
public List<T> getAll()
{
return this.getCurrentSession().createQuery("from " + this.clazz.getName()).list();
}
public void create(final T entity)
{
if (entity != null)
{
try
{
this.getCurrentSession().persist(entity);
}
catch (PersistentObjectException e)
{
this.getCurrentSession().saveOrUpdate(entity);
}
}
}
public void update(final T entity)
{
if (entity != null)
{
this.getCurrentSession().merge(entity);
}
}
public void delete(final T entity)
{
if (entity != null)
this.getCurrentSession().delete(entity);
}
public void deleteById(final Long entityId)
{
final T entity = this.getById(entityId);
if (entity != null)
this.delete(entity);
}
public void setSessionFactory(SessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}
protected final Session getCurrentSession()
{
return this.sessionFactory.getCurrentSession();
}
public List<T> getWithCriteria(List<Criterion> criteria)
{
Criteria c = this.getCurrentSession().createCriteria(this.clazz);
for (Criterion cr : criteria)
{
c.add(cr);
}
return c.list();
}
}
ImageDAO.java
package com.smiechmateusz.dao;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.smiechmateusz.model.Image;
#Service
#Transactional()
public class ImageDAO extends AbstractDAO
{
public ImageDAO()
{
super(Image.class);
}
}
ArticleDAO.java
package com.smiechmateusz.dao;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.smiechmateusz.model.Article;
#Service
#Transactional()
public class ArticleDAO extends AbstractDAO
{
public ArticleDAO()
{
super(Article.class);
}
}
Image.java
package com.smiechmateusz.model;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="Image")
public class Image implements Serializable
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
long id;
#ManyToOne(fetch=FetchType.LAZY, cascade=CascadeType.ALL)
#JoinColumn(name="article")
Article article;
#Column(name="path")
String path;
#Column(name="type")
int type;
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public Article getArticle()
{
return article;
}
public void setArticle(Article article)
{
this.article = article;
}
public String getPath()
{
return path;
}
public void setPath(String path)
{
this.path = path;
}
public int getType()
{
return type;
}
public void setType(int type)
{
this.type = type;
}
}
Article.java
package com.smiechmateusz.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
#Table(name="Article")
public class Article implements Serializable
{
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id")
long id;
#Column(name="images")
#OneToMany(targetEntity=com.smiechmateusz.model.Image.class, mappedBy="article",cascade=CascadeType.ALL, fetch=FetchType.LAZY)
List<Image> images;
#Column(name="description")
String description;
#Temporal(TemporalType.DATE)
#Column(name="addDate")
Date addDate;
public Article()
{
this.images = new ArrayList<Image>();
}
public long getId()
{
return id;
}
public void setId(long id)
{
this.id = id;
}
public List<Image> getImages()
{
return images;
}
public void setImages(List<Image> images)
{
this.images = images;
}
public String getDescription()
{
return description;
}
public void setDescription(String description)
{
this.description = description;
}
public Date getAddDate()
{
return addDate;
}
public void setAddDate(Date addDate)
{
this.addDate = addDate;
}
}
I'm using the following code to test:
ApplicationContext context = new ClassPathXmlApplicationContext("spring-hibernate.xml");
Configuration config = (Configuration) context.getBean("hibernateConfiguration");
new SchemaExport(config).create(true, true);
ArticleDAO ad = (ArticleDAO) context.getBean("ArticleDAO");
ImageDAO id = (ImageDAO) context.getBean("ImageDAO");
Article a = new Article();
Image i = new Image();
i.setPath("path");
i.setType(0);
i.setArticle(a);
a.setAddDate(new Date());
a.setDescription("desc");
Image i2 = new Image();
i2.setPath("path2");
i2.setType(1);
i2.setArticle(a);
List<Image> list = new ArrayList<Image>();
list.add(i);
list.add(i2);
ad.create(a);
a.setImages(list);
ad.update(a);
System.out.println(i.getId()); //Returns 0 instead of 1.
DB query:
mysql> SELECT * FROM Image;
+----+-------+------+---------+
| id | path | type | article |
+----+-------+------+---------+
| 1 | path | 0 | 1 |
| 2 | path2 | 1 | 1 |
+----+-------+------+---------+
2 rows in set (0.00 sec)
EDIT:
If I try to get the ID of Article a, it returns valid id (1).
System.out.println(a.getId());
1
The problem is in AbstractDAO.update() method. You're trying to merge everything to the DB, but instead you should save() the new entities.
Take a look at this question Hibernate : Downside of merge() over update()

nullpointer exception in getcurrentsession

I am trying to integrate Hibernate 4.1 with Spring 3.1.3.
//configuration file (beans.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"
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 ">
<bean id="employeeDAObean" class="com.Hib_Spring.EmployeeDAO">
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSourceBean"></property>
<property name="annotatedClasses" value="com.Hib_Spring.Employee"> </property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="dataSourceBean" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost:5432/newdatabase"/>
<property name="username" value="postgres"/>
<property name="password" value="P#ssword"/>
</bean>
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
</beans>
This is my model class
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="employee_new")
public class Employee {
#Id
#Column(name="ID")
private int id;
#Column (name="firstname")
private String first_name;
#Column(name="lastname")
private String last_name;
public Employee() {}
public Employee(int id,String fname, String lname) {
this.first_name = fname;
this.last_name = lname;
}
public int getId() {
return id;
}
public void setId( int id ) {
this.id = id;
}
public String getFirstName() {
return first_name;
}
public void setFirstName( String first_name ) {
this.first_name = first_name;
}
public String getLastName() {
return last_name;
}
public void setLastName( String last_name ) {
this.last_name = last_name;
}
}
Following is my DAO class
import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class EmployeeDAO {
#Autowired
SessionFactory sessionFactory;
public void createEmployee(int id, String fname, String lname)
{
Employee emp1 = new Employee(id,fname,lname);
sessionFactory.getCurrentSession().save(emp1);
}
public List getAllEmployees(){
return sessionFactory.getCurrentSession().createQuery("from employee_new").list();
}
}
My table has three columns ID, firstname,lastname
This is the main class(Client.java)
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Client {
public static void main(String arg[]){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
EmployeeDAO employeedao=context.getBean("employeeDAObean",EmployeeDAO.class);
System.out.println("Entering data in the database");
employeedao.createEmployee(101, "aaa", "bbb");
employeedao.createEmployee(102, "ccc", "ddd");
System.out.println("Reading the data");
List employeelist= employeedao.getAllEmployees();
for(int i=0;i<employeelist.size();i++){
Employee e = (Employee) employeelist.get(i);
System.out.println("Emp No "+e.getId());
System.out.println("FirstName "+e.getFirstName());
System.out.println("LastName "+e.getLastName());
}
}
}
Now my problem is that whenever I try to execute client.java I am getting a nullpointer exception in
sessionFactory.getCurrentSession().save(emp1);
of the EmployeeDAO class.
Right now my table is empty and I am trying to add a record in it. I dont what is the exact mistake I have done. I am sure there should be a silly one. Could someone throw some light on it. Thanks for the help!
You have tx:annotation-driven but I do not see any transaction annotations. Try putting the annotation on the createEmployee method of the dao and that will get it going.

Resources