JPA ManyToMany:将现有对象添加到另一个对象

时间:2017-02-16 02:57:40

标签: java spring jpa spring-boot

我正在使用JPA并想弄清楚多对多关系如何。假设我有一个“商店”和一个“顾客”。这些有很多关系。

所以我的理解是,商店可以拥有许多客户,而客户可以与许多商店相关联。所以我想做的是创建两个商店和几个客户。然后,我想让同一个客户成为商店1和商店2的一部分。但是,当我将商店1保存到客户,然后将同一个客户与商店2相关联时(假设客户在两个商店都有商店) ),我收到此错误消息:传递给持久化的分离实体。

不确定如何解决此问题。任何帮助和评论表示赞赏。提前谢谢!

@Entity
public class Store {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @OneToMany(cascade=CascadeType.ALL, orphanRemoval=true)
    private List<Item> items = new ArrayList<>();

    @ManyToMany(cascade=CascadeType.ALL)
    private List<Customer> customers = new ArrayList<>();

    public List<Customer> getCustomers() {
        return customers;
    }
    public void setCustomers(List<Customer> customers) {
        this.customers = customers;
    }
    public Store() {
    }   
    public Store(String name) {
       this.name = name;
    }   
    public Long getId() {
       return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }   
    public List<Item> getItems() {
        return items;
    }
    public void setItems(List<Item> items) {
        this.items = items;
    } 
    public Store addItem(Item item) {
        items.add(item);
        return this;
    }
}

@Entity 
public class Customer {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;

private String name;

public Long getId() {
    return id;
}
public void setId(Long id) {
    this.id = id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}

}

@Entity  
public class Item {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private BigDecimal price;
    public Item() { }

    public Item(String name, BigDecimal price) {
        this.name = name;
        this.price = price;
    }
    public Item() {
    }   
    public Item(String name, BigDecimal price) {
        this.name = name;
        this.price = price;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
   }    
   public String getName() {
        return name;
   }
   public void setName(String name) {
        this.name = name;
   }
   public BigDecimal getPrice() {
        return price;
   }
   public void setPrice(BigDecimal price) {
        this.price = price;
   }
}

这是使用Spring Boot的驱动程序代码:     Store safeway = new Store(“Safeway4”);

safeway.addItem(new Item("Fuji Apple", new BigDecimal(1)));
safeway.addItem(new Item("Black Grapes", new BigDecimal(2)));
safeway.addItem(new Item("Cheese Pizza", new BigDecimal(10)));

Store bestBuy = new Store("Best Buy4");
bestBuy.addItem(new Item("55 inch TV", new BigDecimal(550)));
bestBuy.addItem(new Item("Bluray Player", new BigDecimal(85)));
bestBuy.addItem(new Item("Nikon SLR", new BigDecimal(1500)));

Customer elf = new Customer();
elf.setName("Elf");
Customer neo = new Customer();
neo.setName("Neo");
safeway.getCustomers().add(elf);
safeway.getCustomers().add(neo);

Customer yoda = new Customer();
yoda.setName("Yoda");
Customer crazy = new Customer();
crazy.setName("Crazy"); 
bestBuy.getCustomers().add(yoda);
bestBuy.getCustomers().add(crazy);

log.debug("adding neo to best buy");           
bestBuy.getCustomers().add(neo); // Adding Neo to both stores! 

log.debug("saving safeway 1");
storeRepository.save(safeway); 
log.debug("saving safeway 1 done");

log.debug("saving bestBuy 1");
storeRepository.save(bestBuy); // error happens here <----------- 
log.debug("saving bestBuy 1 done");

1 个答案:

答案 0 :(得分:0)

如果您移除CascadeType.ALL,则可以避免此问题。

逻辑上,Customer可以存在,而不会与任何Store相关联。这意味着Customer的生命周期应该独立于Store实体的生命周期,因此级联来自Customer的{​​{1}}的任何操作都是错误的。

您可以单独保存Store实例,将保存的实例与相应的Customer相关联,然后单独保存。