Reputation: 415
I am working rest services with spring and hibernate,for updating employee data using below code, but when run I got below error
{
"code": 0,
"message": "org.hibernate.HibernateException: illegally attempted to associate a proxy with two open Sessions"
}
DataDaoImpl.java
@Override
public Employee getEntityById(long id) throws Exception {
session = sessionFactory.openSession();
Employee employee = (Employee) session.load(Employee.class,
new Long(id));
tx = session.getTransaction();
session.beginTransaction();
tx.commit();
return employee;
}
RestController.jav
@RequestMapping(value = "/save/{id}", method = RequestMethod.POST,consumes = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody
Status saveUser(@PathVariable("id") long id,@RequestBody Employee employee) {
Employee employeeupdate = null;
try {
employeeupdate = dataServices.getEntityById(id);
employeeupdate.setFirstName(employee.getFirstName());
employeeupdate.setLastName(employee.getLastName());
employeeupdate.setEmail(employee.getEmail());
employeeupdate.setPhone(employee.getPhone());
dataServices.updateEntity(employeeupdate);
return new Status(1, "Employee updated Successfully !");
} catch (Exception e) {
// e.printStackTrace();
return new Status(0, e.toString());
}
}
@Override
public boolean updateEntity(Employee employeeupdate) throws Exception {
session = sessionFactory.openSession();
tx = session.beginTransaction();
session.update(employeeupdate);
tx.commit();
session.close();
return false;
}
What mistake have I done here?
Upvotes: 0
Views: 4538
Reputation: 40076
In short, you should not create session in your DAO.
Given that you are using Spring, you should avoid manually creating the Session/Transaction. Please make use of Spring to manage the transaction and session creation, by relying on Spring's transaction control and things like LocalEntityManagerFactoryBean
Upvotes: 0
Reputation: 19986
Appart of @StanislavL answer, there are some errors in your code getEntityById()
should be (you need close a session and place a transaction above load()
).
@Override
public Employee getEntityById(long id) throws Exception {
session = sessionFactory.openSession();
tx = session.getTransaction();
session.beginTransaction();
Employee employee = (Employee) session.load(Employee.class,
new Long(id));
tx.commit();
session.close();
return employee;
}
But this variant is not very correct too, you should catch an exception use a finally block and rollback a transaction. The best way is using this pattern doInTransaction().
Update
It is better to get an entity this way
Employee employee = (Employee) session.get(Employee.class, id);
Upvotes: 0
Reputation: 8257
In the getEntityById(...)
method the session is not closed. Close the session using session.close();
before returning the employee and try.
Upvotes: 1
Reputation: 57421
Don't open 2 sessions. Open just one and use it.
place the
session = sessionFactory.openSession();
tx = session.beginTransaction();
In the beginning of saveUser() and pass the session/transaction to the methods. Actually you don't need transaction in the getEntityById() - you change nothing.
Upvotes: 0