Весенняя загрузка Hibernate Отношения многие ко многим. Отдельная сущность передана для сохранения: - PullRequest
0 голосов
/ 06 января 2020

У меня есть 2 сущности Product и ProductOptions со многими взаимоотношениями.

@Entity
public class Product {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    private String description;
    private String productCategory;
    private String optionDescription;
    private BigDecimal productBasePrice;
    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name="product_productoption",joinColumns=@JoinColumn(name="Product_id"), inverseJoinColumns=@JoinColumn(name="ProductOption_id"))
    private Set<ProductOption>productOptions=new HashSet<>();
}

И

@Entity
public class ProductOption {
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    private String productOptionDescription;
    private BigDecimal optionPrice;
    private BigDecimal optionPriceForSmall;
    private BigDecimal optionPriceForNormal;
    private BigDecimal optionPriceForFamily;
    private BigDecimal optionPriceForParty;
    @ManyToMany(mappedBy = "productOptions")
    private Set<Product>product=new HashSet<>();
}

Инициализация данных

private void initProducts() {
    ProductOption productOpton1=new ProductOption("mit Cocktailsauce", new BigDecimal(0), null, null, null, null);

    ProductOption productOpton2=new ProductOption("mit Joghurtsauce", new BigDecimal(0), null, null, null, null);
    ProductOption productOpton3=new ProductOption("ohne Sauce", new BigDecimal(0), null, null, null, null);

    Product product37= new Product("Falafel", ProductCategory.Vegatarische_Döner, "Wahl aus: mit Cocktailsauce, mit Joghurtsauce oder ohne Sauce.",  new BigDecimal(5.00));

    product37.getProductOptions().add(productOpton1);
    product37.getProductOptions().add(productOpton2);
    product37.getProductOptions().add(productOpton3);
    productOpton1.getProduct().add(product37);
    productOpton2.getProduct().add(product37);
    productOpton3.getProduct().add(product37);
    Product product38= new Product("Falafel Yufka Dürüm", ProductCategory.Vegatarische_Döner, "Wahl aus: mit Cocktailsauce, mit Joghurtsauce oder ohne Sauce.",  new BigDecimal(5.50));
    product38.getProductOptions().add(productOpton1);
    product38.getProductOptions().add(productOpton2);
    product38.getProductOptions().add(productOpton3);
    productOpton1.getProduct().add(product38);
    productOpton2.getProduct().add(product38);
    productOpton3.getProduct().add(product38);



        this.productRepository.save(product37);
        this.productRepository.save(product38);     

}

это дает мне следующее исключение

Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: xx.xy.zz ProductOption
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:127) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:726) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:694) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]
    at org.hibernate.engine.spi.CascadingActions$7.cascade(CascadingActions.java:298) ~[hibernate-core-5.4.9.Final.jar:5.4.9.Final]

но если я не сохраню продукт38

this.productRepository.save(product38); 

, то у меня нет проблем. кажется, что я не могу сохранить один и тот же экземпляр несколько раз? поскольку productOption 1-3 уже сохранен с product37?

product38.getProductOptions().add(productOpton1);
        product38.getProductOptions().add(productOpton2);
        product38.getProductOptions().add(productOpton3);

Должен ли я создавать новый экземпляр каждый раз, когда содержимое одинаково. Есть ли обходной путь здесь?

Пожалуйста, совет. Спасибо.

** Обновление ** не забудьте упомянуть, что Equals реализован в обеих сущностях.

@ Override

public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    ProductOption other = (ProductOption) obj;
    if (id == null) {
        if (other.id != null)
            return false;
    } else if (!id.equals(other.id))
        return false;
    if (optionPrice == null) {
        if (other.optionPrice != null)
            return false;
    } else if (!optionPrice.equals(other.optionPrice))
        return false;
    if (optionPriceForFamily == null) {
        if (other.optionPriceForFamily != null)
            return false;
    } else if (!optionPriceForFamily.equals(other.optionPriceForFamily))
        return false;
    if (optionPriceForNormal == null) {
        if (other.optionPriceForNormal != null)
            return false;
    } else if (!optionPriceForNormal.equals(other.optionPriceForNormal))
        return false;
    if (optionPriceForParty == null) {
        if (other.optionPriceForParty != null)
            return false;
    } else if (!optionPriceForParty.equals(other.optionPriceForParty))
        return false;
    if (optionPriceForSmall == null) {
        if (other.optionPriceForSmall != null)
            return false;
    } else if (!optionPriceForSmall.equals(other.optionPriceForSmall))
        return false;
    if (productOptionDescription == null) {
        if (other.productOptionDescription != null)
            return false;
    } else if (!productOptionDescription.equals(other.productOptionDescription))
        return false;
    return true;
}

Сначала сохранение ProductOptions и повторное их использование не приводит к либо помочь.

private void initProducts() {
    ProductOption productOpton1=new ProductOption("mit Cocktailsauce", new BigDecimal(0), null, null, null, null);

    ProductOption productOpton2=new ProductOption("mit Joghurtsauce", new BigDecimal(0), null, null, null, null);
    ProductOption productOpton3=new ProductOption("ohne Sauce", new BigDecimal(0), null, null, null, null);

    Product product37= new Product("Falafel", ProductCategory.Vegatarische_Döner, "Wahl aus: mit Cocktailsauce, mit Joghurtsauce oder ohne Sauce.",  new BigDecimal(5.00));

    product37.getProductOptions().add(productOpton1);
    product37.getProductOptions().add(productOpton2);
    product37.getProductOptions().add(productOpton3);
    productOpton1.getProduct().add(product37);
    productOpton2.getProduct().add(product37);
    productOpton3.getProduct().add(product37);
    Product product38= new Product("Falafel Yufka Dürüm", ProductCategory.Vegatarische_Döner, "Wahl aus: mit Cocktailsauce, mit Joghurtsauce oder ohne Sauce.",  new BigDecimal(5.50));
    product38.getProductOptions().add(productOpton1);
    product38.getProductOptions().add(productOpton2);
    product38.getProductOptions().add(productOpton3);
    productOpton1.getProduct().add(product38);
    productOpton2.getProduct().add(product38);
    productOpton3.getProduct().add(product38);


    this.productOptionRepository.save(productOpton1);
    this.productOptionRepository.save(productOpton2);
    this.productOptionRepository.save(productOpton3);
        this.productRepository.save(product37);
        this.productRepository.save(product38);




}

1 Ответ

1 голос
/ 06 января 2020

Вам нужно @Transactional в методе initProducts, если вы хотите сохранить несколько разных данных в одном методе. Кажется, проблема в том, что на тот момент, когда вы хотите сохранить product38, ProductOptions еще не сохранен в БД. С пружиной @Transactional создайте транзакцию, и все операции будут выполнены.

...