Spring Boot休眠多对多关系.分离的实体已传递以保留: [英] Spring boot Hibernate Many to Many Relationship. Detached entity passed to persist:

查看:46
本文介绍了Spring Boot休眠多对多关系.分离的实体已传递以保留:的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个具有许多关系的实体Product和ProductOptions.

I have 2 entities Product and ProductOptions with manytomany Relationship.

@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

but if i do not persist the product38

this.productRepository.save(product38); 

那我没有任何问题.似乎我无法多次持久存储同一实例?因为productOption 1-3已经与product37保持一致?

then i do not have any problem . it seems like i cannot persist the same instance multiple times ?since productOption 1-3 are already persisted with product37 ?

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

尽管内容相同,我是否必须每次都创建新实例吗?这里有什么解决方法吗?

Do i have to create new instance everytime though content is same . Is there any workaround here ?

请咨询.谢谢.

**更新**忘了提在两个实体中都实现了等于.

**Update ** forget to mention that Equals is implemented in both the entities.

@Override

@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并重新使用它们也无济于事.

Saving ProductOptions first and reusing them does not help either.

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);




}

推荐答案

如果要在一个方法中保存多个不同的数据,则需要在initProducts方法中使用@Transactional.问题似乎是,到目前为止,您要保存product38的ProductOptions尚未保存在DB中.使用@Transactional spring创建一个事务,然后将执行所有操作.

You need @Transactional at the method initProducts if you want to save multiple different data in one method. The problem seems to be, that to the moment that you want to save product38 the ProductOptions not saved in DB yet. With @Transactional spring create a transaction and all operations will be performed.

这篇关于Spring Boot休眠多对多关系.分离的实体已传递以保留:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆