Java 删除时删除分离的实例错误
当我试图从REST控制器中删除下面的Customer对象时,出现“删除分离的实例”异常 日志:Java 删除时删除分离的实例错误,java,spring,hibernate,rest,Java,Spring,Hibernate,Rest,当我试图从REST控制器中删除下面的Customer对象时,出现“删除分离的实例”异常 日志: org.springframework.dao.InvalidDataAccessApiUsageException: Removing a detached instance com.test.model.Customer#1750; nested exception is java.lang.IllegalArgumentException: Removing a detached instanc
org.springframework.dao.InvalidDataAccessApiUsageException: Removing a detached instance com.test.model.Customer#1750; nested exception is java.lang.IllegalArgumentException: Removing a detached instance com.test.model.Customer#1750
@Entity
public class Customer{
@Id
private Long id;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
// other stuff with getters/setters
}
@Controller
@RequestMapping("/shop/services/customers")
public class CustomerRESTController {
/**
* Deletes a customer
*/
@RequestMapping( value="/{id}", method=RequestMethod.DELETE)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteCustomer(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) throws Exception {
Customer customer = customerService.getById(id);
if(customer != null){
customerService.delete(customer);
}else{
response.sendError(503, "No Customer found for ID : " + id);
}
}
// other stuff
}
域:
org.springframework.dao.InvalidDataAccessApiUsageException: Removing a detached instance com.test.model.Customer#1750; nested exception is java.lang.IllegalArgumentException: Removing a detached instance com.test.model.Customer#1750
@Entity
public class Customer{
@Id
private Long id;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
// other stuff with getters/setters
}
@Controller
@RequestMapping("/shop/services/customers")
public class CustomerRESTController {
/**
* Deletes a customer
*/
@RequestMapping( value="/{id}", method=RequestMethod.DELETE)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteCustomer(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) throws Exception {
Customer customer = customerService.getById(id);
if(customer != null){
customerService.delete(customer);
}else{
response.sendError(503, "No Customer found for ID : " + id);
}
}
// other stuff
}
休息控制器:
org.springframework.dao.InvalidDataAccessApiUsageException: Removing a detached instance com.test.model.Customer#1750; nested exception is java.lang.IllegalArgumentException: Removing a detached instance com.test.model.Customer#1750
@Entity
public class Customer{
@Id
private Long id;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name="COUNTRY_ID", nullable=false)
private Country country;
// other stuff with getters/setters
}
@Controller
@RequestMapping("/shop/services/customers")
public class CustomerRESTController {
/**
* Deletes a customer
*/
@RequestMapping( value="/{id}", method=RequestMethod.DELETE)
@ResponseStatus(HttpStatus.NO_CONTENT)
public void deleteCustomer(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) throws Exception {
Customer customer = customerService.getById(id);
if(customer != null){
customerService.delete(customer);
}else{
response.sendError(503, "No Customer found for ID : " + id);
}
}
// other stuff
}
我正在从数据库中获取客户对象,但仍处于休眠状态。
任何建议???在当前会话(或更好的事务)中分离实体。因为您在Spring中,所以使用for事务行为是很常见的。有了这样的Hibernate,提交后会自动清除持久性上下文(当用作JPA解决方案时也是如此) 通常Hibernate不会清除会话的持久性上下文,因此在提交后实体通常不会分离。(这在分布式环境中是不安全的,但如果仅使用Hibernate访问数据库并使用像Ehcache这样的分布式缓存,则可以保存) 解决方案:
session.merge(object)
将实体重新附加到当前会话对象的持久性上下文
它实际上不是合并,而是重新连接,如果Hibernate不确定实体的当前状态是否反映了正确的数据库缓存,它将重新加载实体。(并添加版本属性(@version)出现时的特殊行为)
顺便说一下,Hibernate的文档说明:
将给定对象的状态复制到具有相同标识符的持久对象上。如果当前没有与会话关联的持久实例,则将加载该实例
更新
看到代码后,这看起来像是一个事务性问题。请检查您的customerService.getById(id)和customerService.delete(customer)服务调用是否导致事务提交。您需要将两者放在同一个事务中
您还可以做一件事来解决您的问题:
public void deleteCustomer(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) throws Exception {
boolean wasDeleted = customerService.delete(id);
if(!wasDeleted)
response.sendError(503, "No Customer found for ID : " + id);
}
}
这样您就不需要两次服务呼叫。实际上,在高级服务调用中使用hibernate实体是不典型的(但对于不同的体系结构,这可能有所不同。我没有太多地使用Spring)。您能展示一下
customerService
的代码吗?当然……这里是:@service(“customerService”)公共类customerService Impl{public Customer getById(Long id){return customerDAO.getById(id);}}
谢谢!…您的建议有效。我已将控制器中的检索和删除逻辑移动到单个服务方法。