Временный экземпляр должен быть сохранен перед текущей операцией над полем @ManytoOne, ссылающимся на поле без идентификатора - PullRequest
0 голосов
/ 19 июня 2019

У меня возникла эта классическая проблема, но я нигде не могу найти никого с такой же точной проблемой.

Это две рассматриваемые таблицы

    Prices            OverrideCategory             
______________       __________________    
|id          |       |id              |
|bandId      |       |storeId         |
|sku         |       |priceCategory   |
|category    |       |overridePrice   |
|oldPrice    |       |reason          |
|newPrice    |       |author          |
|updateUTC   |       |updateUTC       |
______________       __________________

Вот какЯ сопоставляю эти две таблицы.

@Entity
@Data
@NoArgsConstructor
@Table(name = "overrideCategory")
public class OverrideCategoryEntity extends Author {

    @Builder
    public OverrideCategoryEntity(@NotNull String reason, @NotNull String author, StoreEntity storeId, PricesEntity priceCategory, @NotNull BigDecimal overridePrice) {
        super(reason, author);
        this.storeId = storeId;
        this.priceCategory = priceCategory;
        this.overridePrice = overridePrice;
    }

    @JoinColumn(name = "storeId", nullable = false)
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    private StoreEntity storeId;

    @JoinColumn(name = "priceCategory", referencedColumnName = "category", nullable = false)
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    private PricesEntity priceCategory;

    @NotNull
    private BigDecimal overridePrice;
@Entity
@Data
@NoArgsConstructor
@Table(name = "prices")
public class PricesEntity extends Price {

    @Builder
    public PricesEntity(@NotNull BigDecimal oldPrice, @NotNull BigDecimal newPrice, BandsEntity bandId, @NotNull String sku, @NotNull String category) {
        super(oldPrice, newPrice);
        this.bandId = bandId;
        this.sku = sku;
        this.category = category;
    }

    @JoinColumn(name = "bandId", nullable = false)
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    private BandsEntity bandId;

    @NotBlank
    private String sku;

    @NotBlank
    private String category;

Это мой контроллер

@RestController
public class OverrideCategoryController {

    @Autowired
    private ModelMapper modelMapper;

    private final OverrideCategoryRepository repository;


    public OverrideCategoryController(OverrideCategoryRepository repository) {
        this.repository = repository;
    }

    @PostMapping("/categories")
    OverrideCategoryEntity newOverrideCategory(@RequestBody @Valid OverrideCategory overrideCategory) {
        OverrideCategoryEntity entity = modelMapper.map(overrideCategory, OverrideCategoryEntity.class);
        return repository.save(entity);
    }

Это мой репозиторий

public interface OverrideCategoryRepository extends JpaRepository<OverrideCategoryEntity, BigInteger> {

}

Это DTOкоторый я использую для конечной точки

@Data
public class OverrideCategory extends Author {

    @NotNull
    private BigInteger storeId;

    @NotBlank
    private String priceCategory;

    @NotNull
    @Min(value = 0)
    private BigDecimal overridePrice;

}

Это мой Json, который я отправляю

{
    "storeId": 1,
    "priceCategory": "category",
    "overridePrice": 50.23,
    "reason": "reason",
    "author": "author"
}

Это ошибка, которую я получаю

2019-06-19 15:39:07.850  WARN 27026 --- [nio-8118-exec-1] o.h.a.i.UnresolvedEntityInsertActions    : HHH000437: Attempting to save one or more entities that have a non-nullable association with an unsaved transient entity. The unsaved transient entity must be saved in an operation prior to saving these dependent entities.
    Unsaved transient entity: ([com.priceengine.domain.PricesEntity#<null>])
    Dependent entities: ([[com.priceengine.domain.OverrideCategoryEntity#<null>]])
    Non-nullable association(s): ([com.priceengine.domain.OverrideCategoryEntity.priceCategory])
2019-06-19 15:39:07.910 ERROR 27026 --- [nio-8118-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : com.priceengine.domain.OverrideCategoryEntity.priceCategory -> com.priceengine.domain.PricesEntity; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : com.priceengine.domain.OverrideCategoryEntity.priceCategory -> com.priceengine.domain.PricesEntity] with root cause


org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : com.priceengine.domain.OverrideCategoryEntity.priceCategory -> com.priceengine.domain.PricesEntity; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: Not-null property references a transient value - transient instance must be saved before current operation : com.priceengine.domain.OverrideCategoryEntity.priceCategory -> com.priceengine.domain.PricesEntity

У таблицы prices есть данные, я попробовал варианты каскада, я подумал, что это может быть отображение между DTO и сущностями, но отображение работает для других таблиц, которые у меня есть.Другие таблицы имеют только одну @ ManyToOne аннотацию, и они ссылаются на идентификатор из родительской таблицы.

В этой таблице есть две @ ManyToOne отношений и один из них не ссылается на id, это должно быть проблемой?

1 Ответ

0 голосов
/ 24 июня 2019

Мне удалось решить проблему, изменив отображение сущности.

@Entity
@Data
@NoArgsConstructor
@Table(name = "overrideCategory")
public class OverrideCategoryEntity extends Author {

    @Builder
    public OverrideCategoryEntity(@NotNull String reason, @NotNull String author, BigInteger storeId, String priceCategory, @NotNull BigDecimal overridePrice) {
        super(reason, author);
        this.storeId = storeId;
        this.priceCategory = priceCategory;
        this.overridePrice = overridePrice;
    }

    @JoinColumn(name = "storeId", insertable = false, updatable = false, nullable = false)
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    private StoreEntity storeEntity;

    @JoinColumn(name = "priceCategory", referencedColumnName = "category", insertable = false, updatable = false, nullable = false)
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    private PricesEntity pricesEntity;

    @Column(name = "priceCategory")
    private String priceCategory;

    @Column(name = "storeId")
    private BigInteger storeId;

    @NotNull
    private BigDecimal overridePrice;

Я много тестировал, и все работает нормально, но я не думаю, что это правильный способ картирования моей сущности. Есть какая-то проблема с отображением сущности, подобной этой?

...