#java #spring #spring-boot #spring-data #dto
#java #spring #spring-boot #spring-данные #dto
Вопрос:
У меня следующая конфигурация:
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. Супермаркет и магазин равны нулю для ProductPriceResponse.
Ну, тогда я изменил каскад отношений атрибутов хранилища.
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "SUPERMARKET_STORE_ID", nullable = false)
private SupermarketStoreEntity store;
И я получил эту ошибку:
«отдельная сущность передана в persist: model.SupermarketStoreEntity; вложенным исключением является org.hibernate.PersistentObjectException: отдельная сущность передается в persist: model.SupermarketStoreEntity»
Это имеет смысл. Modelmapper преобразует длинный StoreID в SupermarketStoreEntity с единственным идентификатором и отсоединяется…
наконец, мой вопрос: какова наилучшая практика?
Должен ли я получать StoreID и не преобразовываться в отделенный от SupermarketStoreEntity и находить SupermarketStoreEntity с вашим StoreID в ProductPriceControllerImpl?
Или нет. Должен ли я удалить каскад и после сохранения ProductPriceEntity я должен получить сохраненный ProductPriceEntity? Я подозреваю, что магазин и супермаркет все равно получат null, потому что каскада там нет.
спасибо всем
Ответ №1:
Думаю, лучше всего ввести класс @Service, где у вас есть метод с аннотацией @Transactional . Служба внедряется в контроллер, и там происходит вся загрузка и сохранение объектов. Это должно помочь с ошибкой отсоединения.
Я не большой поклонник атрибута cascade и предпочел бы делать это в коде, но это скорее мнение.
Может быть, вы хотите взглянуть на https://bootify.io — вы можете определить свою базу данных с помощью REST api там и получить представление о лучших практиках для контроллеров и служб.:)
Комментарии:
1. Я уже использую класс обслуживания с транзакционным и метод с транзакционным тоже …. но моя проблема сохраняется! Если я использую CascadeType.ALL (или CascadeType. СОХРАНЯЕТСЯ) Я получил ошибку отсоединения…. Если я не использую каскад, он работает нормально, но я не получаю детализации хранилища, потому что каскада нет. Я не знаю! Должен ли я получить объект хранилища перед сохранением? Я хотел бы просто передать идентификатор хранилища и объекта хранилища выборки данных Spring до сохранения ….. или после …. для я использую в своем ответе….
2. Для меня звучит так, как будто отсоединение происходит от фактического каскада: вы удаляете объект, и из-за каскада StoreDetails также удаляется. Теперь имеющиеся у вас данные хранилища отсоединены, поскольку они больше не существуют. Я бы попытался сделать это с помощью Cascade NONE и удалить связанные объекты отдельно. Но действительно сложно помочь вам дальше удаленно.