好友。
我对Hibernate的JPA实现有一个问题。我使用spring-boot-starter数据jpa和PostgreSql v9。
我有两个实体通过OneToMany&ManyToOne:
@Entity
public class ShoppingCart {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@OneToMany(mappedBy = "shoppingCart", cascade = {CascadeType.ALL})
private List<Good> goods = new ArrayList<>();
public void addGood(Good good) {
good.setShoppingCart(this);
goods.add(good);
}
public Good removeGood(Good good) {
goods.remove(good);
good.setShoppingCart(null);
return good;
}
public ShoppingCart() {
}
public List<Good> getGoods() {
return goods;
}
public ShoppingCart(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
第二个实体是
@Entity
public class Good {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "cart_id")
@JsonIgnore
private ShoppingCart shoppingCart;
public ShoppingCart getShoppingCart() {
return shoppingCart;
}
public void setShoppingCart(ShoppingCart shoppingCart) {
this.shoppingCart = shoppingCart;
}
public Good(String name) {
this.name = name;
}
public Good() {
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
}
我还使用CrudRepository访问ShoppingCart
public interface ShoppingCartRepository extends CrudRepository<ShoppingCart, Long> {}
当我试图填满现有的购物车时,我的数据库中有两件商品。这是一个将一些商品添加到现有购物车中的代码:
ShoppingCart cart = shoppingCartRepository.findOne(id);
cart.addGood(new Good("Butter"));
return shoppingCartRepository.save(cart);
在"好"表中,我现在有两个具有不同PKey和相同数据的元素
5;"Butter";100
6;"Butter";100
为什么会发生这种情况?
此外,当我试图在repository.save行插入断点时,我在购物车的商品列表中只看到一个商品。
因此,问题得到了解决。
第一种解决方法是用保存代码@Transactional创建方法。
第二种方法是使用getGoods()代替商品。我们应该更改这个代码
public void addGood(Good good) {
good.setShoppingCart(this);
goods.add(good);
}
public Good removeGood(Good good) {
goods.remove(good);
good.setShoppingCart(null);
return good;
}
到这个
public void addGood(Good good) {
good.setShoppingCart(this);
this.getGoods().add(good);
}
public Good removeGood(Good good) {
this.getGoods().remove(good);
good.setShoppingCart(null);
return good;
}
getGoods()强制hibernate更新对象的状态,一切正常。
就我而言,我同时使用两种方式
这是因为您创建了一个没有id的新Good对象。因此Hibernate将生成一个新的id并持久化新对象。如果您不想创建新对象,而只想分配一个已经存在的对象,则必须从数据库中提取现有对象并将其分配给ShoppingCart,或者在创建新的Good对象时添加ID。