【问题标题】:Spring Boot API Rest with DTO and @manytoone relationship - best practiceSpring Boot API Rest 与 DTO 和 @manytoone 关系 - 最佳实践
【发布时间】:2020-11-09 23:32:08
【问题描述】:

我有以下配置:

ProductPriceEntity

@Entity
@Table(name = "PRODUCTPRICE")
public class ProductPriceEntity {

    ...

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "SUPERMARKET_STORE_ID", nullable = false)
    private SupermarketStoreEntity store;

    ...
}

ProductPriceNewRequest

@Setter @Getter
public class ProductPriceNewRequest {

    ...

    private Long storeId;

    ...

}

ProductPriceControllerImpl

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<ProductPriceResponse> save(@PathVariable(value = "product_id", required = true) Long productId, @RequestBody @Valid ProductPriceNewRequest productPriceNewRequest) {
    ProductEntity productEntity = productService.findById(productId);

    ProductPriceEntity productPriceEntity = modelMapper.map(productPriceNewRequest, ProductPriceEntity.class);

    productPriceEntity.setProduct(productEntity);
    productPriceEntity = service.insert(productPriceEntity);

    URI location = ServletUriComponentsBuilder.fromCurrentRequest()
            .path("/{id}")
            .buildAndExpand(productPriceEntity.getId())
            .toUri();


    ProductPriceResponse productPriceResponse = modelMapper.map(productPriceEntity, ProductPriceResponse.class);

    return ResponseEntity.created(location).body(productPriceResponse);

}

ProductPriceResponse

@Getter @Setter
public class ProductPriceResponse {

    ...

    private String supermarket;
    private String store;

    ...
}

它有效,但我无法返回 DTO。 Supermarket 和 store 在 ProductPriceResponse 上为空。

嗯,那我改了级联的store属性关系。

@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "SUPERMARKET_STORE_ID", nullable = false)
private SupermarketStoreEntity store;

我得到了这个错误:

“传递给持久化的分离实体:model.SupermarketStoreEntity;嵌套异常是 org.hibernate.PersistentObjectException:传递给持久化的独立实体:model.SupermarketStoreEntity”

这是有道理的。 Modelmapper 将 long storeId 转换为只有 id 和分离的 SupermarketStoreEntity ...

最后我的问题是:最佳做法是什么?

我是否应该获取 storeId 并且不转换为分离的 SupermarketStoreEntity 并在 ProductPriceControllerImpl 上使用您的 storeId 找到 SupermarketStoreEntity?

或者没有。我应该删除级联并在保存 ProductPriceEntity 后我应该获取保存的 ProductPriceEntity 吗?我怀疑商店和超市仍然会因为级联不存在而变为空。

谢谢大家

【问题讨论】:

    标签: java spring spring-boot spring-data dto


    【解决方案1】:

    猜测最佳实践是引入一个@Service 类,其中有一个带有@Transactional 注释的方法。服务被注入到控制器中,所有实体的加载和保存都在那里发生。这应该有助于解决分离错误。

    我不是 cascade 属性的忠实拥护者,我更愿意在代码中做这些事情 - 但这更多是一种意见。

    也许您想看看https://bootify.io - 您可以在那里使用 REST api 定义您的数据库,并了解控制器和服务的最佳实践。:)

    【讨论】:

    • 我已经在使用带有 Transactional 的服务类和带有 Transactional 的方法......但我的问题仍然存在!如果我使用 CascadeType.ALL(或 CascadeType.PERSIST),则会出现分离错误....我不知道!我应该在坚持之前获得商店实体吗?我只想在持久化之前或之后传递商店的 id 和 Spring Data 获取商店实体......因为我在响应中使用......
    • 对我来说听起来像是分离来自实际的级联:您删除了实体,并且由于级联 StoreDetails 也被删除。现在您拥有的 StoreDetails 已分离,因为它不再存在。我会尝试使用 Cascade NONE 进行此操作,并分别删除相关实体。但是远程帮助你真的很难。
    猜你喜欢
    • 2023-03-18
    • 1970-01-01
    • 2020-09-30
    • 1970-01-01
    • 2020-03-08
    • 2017-11-13
    • 2015-02-23
    • 2010-11-26
    • 2013-10-23
    相关资源
    最近更新 更多