Hibernate创建两行而不是一行



好友。

我对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。

最新更新