延迟初始化和Spring Data DomainClassConverter

时间:2015-09-03 12:53:34

标签: java spring spring-data

我试图使用Spring Data中的DomainClassConverter在控制器中加载实体,然后在服务中使用这些实体。

问题是当我从我的服务访问延迟加载的集合时,我得到一个LazyInitializationException。

向控制器添加Transactional注释没有帮助,我想转换发生在控制器事务开始之前。

有没有办法在这种用例中使用这个转换器?我可以将实体重新连接到当前会话吗?

我的控制器:

@RestController
@RequestMapping("/api/quotation-requests/{id}/quotation")
public class QuotationResource {

    @RequestMapping(value = "/lines", method = RequestMethod.POST, params="freeEntry")
    @Timed
    public ResponseEntity<PricingLineDTO> addFreeEntryLine(@PathVariable("id") Quotation quotation, @RequestBody PricingLineDTO pricingLineTo)
    {
        PricingLine pricingLine = conversionService.convert(pricingLineTo, PricingLine.class);

        pricingLine = quotationService.addFreeLineToQuotation(quotation, pricingLine);

        return new ResponseEntity<>(conversionService.convert(pricingLine, PricingLineDTO.class), HttpStatus.OK);
    }
}

服务:

@Service
@Transactional
public class QuotationService {

    public PricingLine addFreeLineToQuotation(Quotation quotation, PricingLine pricingLine) {
        quotation.getPricingLines().add(pricingLine); // org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: x.y.z.Quotation.pricingLines, could not initialize proxy
    }
}

和实体

@Entity
public class Quotation {

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<PricingLine> pricingLines = new ArrayList<>();
}

如果不可能,那么我最好的选择是什么:

  • 使控制器事务处理,在其中注入数据存储库,并仍然提供一个服务API,它接受实体参数而不是ID。

缺点:控制器变成了交易,这似乎通常被认为是一种不好的做法;它引入了样板代码。

  • 使Service API将ID作为参数,让控制器退出事务。

缺点:API变得难以阅读,并且可能容易出错,因为每个实体都被称为&#34; Long&#34;对象,尤其是当Service方法需要多个实体作为输入时。例如:

void addUserToGroup(Long userId, Long groupId)

可以轻松切换参数。

0 个答案:

没有答案