简体   繁体   English

旧数据在OneToMany映射中被删除

[英]Old Data is getting deleted in OneToMany Mapping

Product and ProductLine. 产品和ProductLine。 One ProductLine can have many products. 一个产品线可以有许多产品。

Product.java:- Product.java:-

@Entity
    @Table(name ="PRODUCT")
    public class Product {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private int id;
        private String name;
    Product(String name){
            this.name=name;
        }
    }

ProductLine.java ProductLine.java

   public class ProductLine {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private int id;
        @OneToMany(cascade = CascadeType.ALL)
        @JoinTable(name = "PRODUCTLINE_PRODUCT", joinColumns = @JoinColumn(name = "PRODUCTLINE_ID"), inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID"))
        private List<Product> products=new ArrayList<>();

     public ProductLine(String name){
        this.name=name;
        }
    }

ProductLineRepository.java ProductLineRepository.java

 public interface ProductLineRepository extends JpaRepository<ProductLine,Integer> {
            ProductLine findOneById(String id);
        ProductLine findOneByName(String name);
        }

Controller:- 控制器:

In the controller i have a am parsing the list of products associated with the Product from the user in the json form and persisting it into DB. 在控制器中,我正在解析用户以json形式与该产品关联的产品列表,并将其持久保存到数据库中。

public void addData(){
        List<Product> products=new ArrayList<>();
        Product product1=new Product("Iphone");
        Product product2=new Product("Mac");
        products.add(product1);
        products.add(product2);
        ProductLine productLine=productLineRepository.findOneByName("Apple");
        productLine.setProducts(products);
        productLineRepository.save(productLine);
    }

Now if the Product Line "Apple" already exists then it deletes the entry in the Product Line table with the name "Apple" and then again inserts the data "IPhone" and "Mac" . 现在,如果产品线“ Apple”已经存在,那么它将删除产品线表中名称为“ Apple”的条目,然后再次插入数据“ IPhone”和“ Mac”。 But i do not want the old data to be deleted . 但是我不希望删除旧数据。 What should i do? 我该怎么办?

This behavior is called orphanRemoval, when an entity is removed from the relation (this is what you are doing when setting new product list) it will be removed. 此行为称为orphanRemoval,当从关系中删除实体时(这是您在设置新产品列表时所做的事情),它将被删除。

since JPA 2.0 the default value for orphanRemoval is false so if you are using this version or higher this behavior should not be there so i guess you are using lower version, either you use higher version or you can set the orphanRemoval attribute to false 由于JPA 2.0,orphanRemoval的默认值为false,因此,如果您使用的是此版本或更高版本,则不应出现此行为,因此我猜您正在使用较低的版本,或者使用较高的版本,也可以将orphanRemoval属性设置为false

@OneToMany(cascade = CascadeType.ALL, orphanRemoval="false")
@JoinTable(name = "PRODUCTLINE_PRODUCT", joinColumns = @JoinColumn(name = "PRODUCTLINE_ID"), inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID"))
private List<Product> products=new ArrayList<>();

我可以通过使用findByName()方法在持久性上下文中加载名称为“ Apple”的ProductLine来解决此问题,然后将与productLine关联的所有产品作为列表加载并将其添加到新创建的产品列表中。

Maybe I'm wrong... 也许我错了...

but when you use this, seems like a @ManyToMany kind of mapping: 但是当您使用它时,似乎就像@ManyToMany这样的映射:

@OneToMany(cascade = CascadeType.ALL)
@JoinTable(name = "PRODUCTLINE_PRODUCT", joinColumns = @JoinColumn(name = "PRODUCTLINE_ID"), inverseJoinColumns = @JoinColumn(name = "PRODUCT_ID"))

If that's true, the natural behavior it's replace the old list to the new one... If you wanna a @OneToMany behavior you only need this: 如果是这样,那么自然的行为就是将旧列表替换为新列表...如果您想使用@OneToMany行为,则只需要这样做:

@OneToMany(mappedBy = "product", cascade = CascadeType.ALL, fetch = FetchType.LAZY)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM