org.hibernate.HibernateException:非法尝试将代理与两个打开的Sessions关联

时间:2015-12-29 06:13:06

标签: eclipse spring hibernate

我正在使用spring和hibernate进行休息服务,使用下面的代码更新员工数据,但是在运行时我得到了以下错误

{
  "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;  
 }  

我在这里犯了什么错误?

4 个答案:

答案 0 :(得分:1)

getEntityById(...)方法中,会话未关闭。在返回员工之前使用session.close();关闭会话并尝试。

答案 1 :(得分:0)

不要打开2个会话。打开一个并使用它。

放置

session = sessionFactory.openSession();  
tx = session.beginTransaction(); 

在saveUser()的开头,将会话/事务传递给方法。实际上你不需要在getEntityById()中进行交易 - 你什么都不做。

答案 2 :(得分:0)

Appart of @StanislavL回答,您的代码getEntityById()应该有一些错误(您需要关闭会话并将交易置于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;  
 }   

但是这个变体也不是很正确,你应该捕获一个异常使用finally块并回滚一个事务。最好的方法是使用此模式doInTransaction()

<强>更新

最好以这种方式获得实体

Employee employee = (Employee) session.get(Employee.class,  id);

答案 3 :(得分:0)

简而言之,您不应该在DAO中创建会话。

鉴于您使用的是Spring,您应该避免手动创建Session / Transaction。请依靠Spring的事务控制和[Tue Dec 29 13:08:07 2015] [error] [client 127.0.0.1] File does not exist: /var/www/home, referer: http://localhost/cgi-bin/download.cgi

之类的东西,利用Spring来管理事务和会话创建。