I am getting error:
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
If I add the below snippet in DataSourceContext.xml, I don't get any error and the application works as expected.
<bean id="userDAO" class="com.my.portal.user.UserDAOImpl">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
I would like my scan packages and register beans without above snippet in DataSourceContext.xml.
How can I achieve this?
Here are my complete code:
Web.xml
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/*.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
DataSourceContext.xml
<!-- Data Source Setup -->
<bean id="myDS" 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/mydb"/>
<property name="username" value="root"/>
<property name="password" value=""/>
<property name="maxIdle" value="5"/>
<property name="maxActive" value="10"/>
</bean>
<!-- Hibernate Sessionfactory Bean Definition -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="myDS"/>
<property name="annotatedClasses">
<list>
<value>com.my.portal.user.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<!-- Hibernate Transaction Setup -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
User.java
#Entity
#Table(name="USER")
public class User {
#Id
#Column(name="UserId")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int UserId;
private String FirstName;
private String LastName;
public int getUserId() {
return UserId;
}
public void setUserId(int userId) {
UserId = userId;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
#Override
public String toString(){
return "UserId="+UserId+", FirstName="+FirstName+", LastName="+LastName;
}
}
UserController.java
#Controller
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
private UserService userService;
#Autowired
public UserController(UserService userService){
this.userService = userService;
}
#RequestMapping(value = "/user", method = RequestMethod.GET)
public String user(Locale locale, Model model){
model.addAttribute("getUser",userService.getUser());
return "user";
}
UserDAO.java
#Repository
public interface UserDAO {
public List<User> getUser();
}
UserDAOImpl.java
#Repository
#Transactional
public class UserDAOImpl implements UserDAO {
private static final Logger logger = LoggerFactory.getLogger(UserDAOImpl.class);
private SessionFactory sessionFactory;
#Autowired
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
private Session currentSession() {
return sessionFactory.getCurrentSession();
}
#SuppressWarnings("unchecked")
#Override
public List<User> getUser() {
List<User> userList = currentSession().createQuery("from User").list();
return userList;
}
}
userService.java
#Service
public interface UserService {
public String getMessage();
}
UserServiceImpl.java
#Service
public class UserServiceImpl implements UserService {
private UserDAO userDAO;
#Autowired
public void setUserDAO(UserDAO userDAO) {
this.userDAO = userDAO;
}
public String getMessage(){
return "User Registration Page";
}
#SuppressWarnings("unchecked")
#Override
public List<User> getUser(){
logger.info("getUser()");
return this.userDAO.getUser();
}
}
Related
I use JpaRepository to save data, but the hibernate.show_sql shows "select" and won't save data. Following is my service:
#Autowired
private UserRepository userRepository;
#PostConstruct
public void init() {
User admin = new User();
admin.setDisplayName("admin");
admin.setEmailAddress("admin#admin");
admin.setPassword("admin___");
admin.setRegisteredAt(new Date());
admin.setLastAccessAt(new Date());
admin.setUuid(UUID.randomUUID().toString());
try {
System.out.println("before save");
userRepository.save(admin);
System.out.println("after save");
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
The output looks like this:
========before save======
Hibernate: select user0_.uuid as uuid1_0_0_, user0_.display_name as display_2_0_0_, user0_.email_address as email_ad3_0_0_, user0_.last_access_at as last_acc4_0_0_, user0_.password as password5_0_0_, user0_.registered_at as register6_0_0_ from User user0_ where user0_.uuid=?
========after save=======
Following is my applicationContext.xml:
<context:component-scan base-package="test">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/helloworld" />
<property name="username" value="root" />
<property name="password" value="password" />
</bean>
<bean id="myEmf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="test.entity"></property>
<property name="dataSource" ref="myDataSource" />
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
</property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="myDataSource" />
</bean>
<jpa:repositories base-package="test.repository"
entity-manager-factory-ref="myEmf" transaction-manager-ref="transactionManager"></jpa:repositories>
Attached is my class generated by JPA Tools:
#Entity
#NamedQuery(name="User.findAll", query="SELECT u FROM User u")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String uuid;
#Column(name="display_name")
private String displayName;
#Column(name="email_address")
private String emailAddress;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="last_access_at")
private Date lastAccessAt;
private String password;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="registered_at")
private Date registeredAt;
public User() {
}
public String getUuid() {
return this.uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getDisplayName() {
return this.displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
public String getEmailAddress() {
return this.emailAddress;
}
public void setEmailAddress(String emailAddress) {
this.emailAddress = emailAddress;
}
public Date getLastAccessAt() {
return this.lastAccessAt;
}
public void setLastAccessAt(Date lastAccessAt) {
this.lastAccessAt = lastAccessAt;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getRegisteredAt() {
return this.registeredAt;
}
public void setRegisteredAt(Date registeredAt) {
this.registeredAt = registeredAt;
}
}
Since you're using JPA, the transaction manager should be a JpaTransactionManager, not a DataSourceTransactionManager.
This is not a duplicate of this question. So please don't close it for "is duplicate of" reasons..
I am trying to autowire a private field in my service class using this tutorial. My problem is that restaurantOwnerRepository remains null and does not get initialized.
servlet-context.xml
<context:component-scan base-package="com.mahlzeit.web.server" />
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
</bean>
<tx:annotation-driven />
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="restaurantOwnerRepository" class="com.mahlzeit.web.server.dao.RestaurantOwnerRepository">
<constructor-arg>
<ref bean="sessionFactory" />
</constructor-arg>
</bean>
Service code:
#Component
public class RestaurantInformationServiceImpl extends XsrfProtectedServiceServlet implements RestaurantInformationService {
private static final long serialVersionUID = -4088840947018614411L;
#Autowired
private RestaurantOwnerRepository restaurantOwnerRepository;
private final static Logger logger = Logger.getLogger(RestaurantInformationServiceImpl.class);
#Override
public List<RestaurantDTO> getAvailableRestaurants() {
// restaurantOwnerRepository is 'null'
List<Restaurant> availableRestaurants = restaurantOwnerRepository.getAvailableRestaurants(getSessionId());
return null;
}
private String getSessionId() {
HttpServletRequest httpRequest = getThreadLocalRequest();
return httpRequest.getSession().getId();
}
}
RestaurantOwnerRepository.java
public class RestaurantOwnerRepository implements RestauranOwnerDAO {
private SessionFactory sessionFactory;
public RestaurantOwnerRepository(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
// ..
}
What could be the reason for this?
here is a sample controller for your example , you should define the bean in your context.xml or if you place it in this package : com.mahlzeit.web.server it will be managed by spring automatically , cause as i see you have placed the context:component-scan
#Controller
public class RestaurantInformationServiceImpl {
#Autowired
private RestaurantOwnerRepository restaurantOwnerRepository;
#RequestMapping(value="/")
public #ResponseBody ModelAndView getRestaurants(
HttpServletRequest request,
HttpServletResponse response) {
ModelAndView model = new ModelAndView("yourPage");
List<?> rests = restaurantOwnerRepository.getAvailableRestaurants(httpRequest.getSession().getId());
model.addObject("restList", rests );
return model;
}
}
I am trying to use the annotation #Transactional to access my MySQL using Hibernate, Spring and JSF. My problem is:
When I use the annotation #Transactional at my managedBean to make a query I got this error:
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
at org.springframework.orm.hibernate3.SpringSessionContext.currentSession(SpringSessionContext.java:65)
at org.hibernate.impl.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:687)
at br.com.rpg.DAO.AbstractDAO.getCurrentSession(AbstractDAO.java:14)
at br.com.rpg.DAO.CountryDAO.findAll(CountryDAO.java:14)
at br.com.rpg.managedBeans.SignupBean.init(SignupBean.java:45)
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)
I don't know what I'm doing wrong. My code and xml config is:
application-config.xml
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="br.com.rpg.DO" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
</props>
</property>
</bean>
<context:component-scan base-package="br.com.rpg" />
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
My MB
#Named
#Scope("request")
public class SignupBean implements Serializable {
private static final long serialVersionUID = 1787096549063029840L;
#Inject
private CountryDAO country;
#Inject
private UserDAO user;
private Map<String, Integer> countries;
private Integer selected;
private String username;
private String password;
#PostConstruct
#Transactional
public void init() {
List<CountryDO> findAll = country.findAll();
countries = new HashMap<String, Integer>();
for (CountryDO countryDO : findAll) {
countries.put(countryDO.getName(), countryDO.getId());
}
}
public Map<String, Integer> getCountries() {
return countries;
}
public void setCountries(Map<String, Integer> countries) {
this.countries = countries;
}
public Integer getSelected() {
return selected;
}
public void setSelected(Integer selected) {
this.selected = selected;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
My Country DAO has the #Named annotation. Someone could help me?
Thx.
you have applied #PostConstruct and #Transactional on init method. init method would be called before applying any AOP Proxy interceptor is applied because of #PostConstruct. Hence at the time of invoking init there is no transaction proxy applied. if you need to call init method on Application startup use ApplicationEvent
I am facing a problem, when I tried to insert a data into Database through JPA (#persistanceContex)
Observations
Not getting any errors;
Record is not storing into database (save)
When I tried with listAll() ; it retrieving the data from database
Domain
#Entity
public class Test {
#Id
private int id;
#Column(name="full_name")
private String fullName;
#Column(name="mobile_number")
private int mobileNumber;
.....
}
DAO Class
#Repository("testDAO")
#Transactional
public class TestDAO {
private EntityManager entityManager;
#PersistenceContext(unitName="CRUD_Test_Annotation")
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void save(Test test){
entityManager.persist(test);
}
}
Service
#Service("testService")
#Transactional
public class TestService {
private static final Logger logger = LoggerFactory.getLogger(TestService.class);
#Autowired(required=true)
private TestDAO testDAO;
public void save(Test test){
logger.info("TestService::save()");
testDAO.save(test);
}
public void list(){
testDAO.getAll();
}
}
Controller
#RequestMapping(value = "/add", method = RequestMethod.GET)
public String add(Locale locale, Model model) {
Test test = new Test();
test.setId(xx);
test.setFullName("xxxxx");
test.setMobileNumber(yyyyyy);
testService.save(test);
return "home";
}
application-context.xml
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- Declare a JPA entityManagerFactory-->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml"></property>
<property name="persistenceUnitName" value="CRUD_Test_Annotation" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
</bean>
</property>
</bean>
<!-- Declare a transaction manager-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
First of all, you don't need two transaction boundaries, I suggest you remove #Transactional from your DAO and keep the one in your service.
Start by verifying that spring-transaction has initiated a transaction: Use the debugger and stop the application after the transaction boundary, for instance in your TestService.save-method. If transactions are running, you will see org.springframework.transaction.interceptor.TransactionInterceptor#invoke in the call stack. If you don't see the TransactionInterceptor, then that's your problem. Post your persistence.xml file if transactions are running.
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.