Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 转换事务中的实体时LazyInitializationException异常_Java_Spring_Hibernate_Jackson_Spring Data - Fatal编程技术网

Java 转换事务中的实体时LazyInitializationException异常

Java 转换事务中的实体时LazyInitializationException异常,java,spring,hibernate,jackson,spring-data,Java,Spring,Hibernate,Jackson,Spring Data,在将域对象从数据库转换为客户端的资源对象的过程中,我遇到了一个延迟加载字段的问题 Customer:使用惰性字段从数据库加载的实体 FullCustomer:将发送到客户端的实体 服务层: @Transactional(readOnly=true) public Customer getById(Long id){ return customerRepository.getById(id); } @Autowired private ResourceAssembler<Cus

在将域对象从数据库转换为客户端的资源对象的过程中,我遇到了一个延迟加载字段的问题

  • Customer
    :使用惰性字段从数据库加载的实体
  • FullCustomer
    :将发送到客户端的实体
服务层:

@Transactional(readOnly=true)
public Customer getById(Long id){
    return customerRepository.getById(id);
}
@Autowired
private ResourceAssembler<Customer, FullCustomer> converter;

@RequestMapping(...)
public final FullCustomer getCustomerById(long cid) {
    Customer customer = customerService.getById(cid);
    return converter.convert(customer);
}
控制器:

@Transactional(readOnly=true)
public Customer getById(Long id){
    return customerRepository.getById(id);
}
@Autowired
private ResourceAssembler<Customer, FullCustomer> converter;

@RequestMapping(...)
public final FullCustomer getCustomerById(long cid) {
    Customer customer = customerService.getById(cid);
    return converter.convert(customer);
}
因此,我的控制器使用转换器将数据库实体转换为客户端的实体。转换触发加载其他延迟加载的实体

我的问题:尽管convert函数打开了一个新的事务(
打开了
打印
true)
,但我得到了以下异常:

org.springframework.http.converter.HttpMessageNotWritableException: 
    Could not write content: failed to lazily initialize a collection of role: [..], could not initialize proxy - no Session (..); 
    nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: ...
在使用BeanUtils之前访问延迟加载的字段时,我得到以下结果:

org.hibernate.LazyInitializationException: 
    failed to lazily initialize a collection of role: [..], could not initialize proxy - no Session

为什么会发生这种情况?

您从一个事务加载客户,而该事务不会初始化延迟加载的字段。然后提交该事务并关闭关联的Hibernate会话,从而使客户实体分离。然后启动另一个事务,尝试初始化分离客户的惰性字段

这是行不通的:您需要从加载客户的事务中加载惰性字段。所以

  • 使控制器方法具有事务性,或
  • 初始化getById()中的惰性字段,或
  • 在存储库中使用联接获取,以确保查询加载客户和所需的关联,或者
  • 使getById()返回一个FullCustomer
  • 使用OpenEntityManagerView拦截器/过滤器(并使转换器非事务性)

是否有办法重新连接现有实体?加载我的服务层内的字段不是一个选项,将
@Transactional
添加到我的控制器无法创建事务。否。您将不得不根据实体的ID重新加载实体,从而使您的服务层完全无用。第五个选项是使用OpenEntityManagerView拦截器/过滤器。