当前位置: 首页 > 知识库问答 >
问题:

双向实体-覆盖数据库中的对象并Hibernate正在进行插入而不是更新

任飞鸣
2023-03-14

当我试图用一个接一个添加的新值更新购物车的内容时,我遇到了一个问题。我使用Spring boot和Hibernate,JPA库,MySQL数据库和一个用vanilla JS构建的前端。我将在下面几行描述我的问题。

我有一个如下所示的用户实体:

@Entity
@Table(name = "users")
@Getter
@Setter
public class User {

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

    private String username;

    private String password;

    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
    private Set<Role> roles;


    @Column(name = "cartprod_id")
    @OneToMany(cascade = {CascadeType.ALL})
    private List<CartItem> cartProduct;

此实体具有列表

@Entity
@Getter
@Setter
public class CartItem {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "product_id")
    private int productId;
    @JsonIgnore
    @ManyToOne
    private User user;
}

上述代码的想法是有一种方法来保持用户的产品购物车的状态。

流程如下:

每次用户在购物车中添加产品时,我都会从前端发出请求,发生这种情况时,我会使用 CartItem 实体将购物车的内容(仅包含产品 ID)保存在数据库中。

问题所在

使用这种方法,它不是只保存添加到购物车的最后一个产品(或者用类似于更新的新值完全替换购物车),而是一遍又一遍地插入同一个对象,但使用所有新的附加值,而不是覆盖数据库中的旧对象(表)。这方面的一个例子将在第一张图片中。正如您所看到的,我首先向购物车添加了一个id为327的产品。

接下来,我将添加一个id为328的产品,但它也会第二次添加327,这会继续下去,我添加的产品越多。最后一段代码包含我的控制器代码。

 @PostMapping("/savecart")
    public ResponseEntity<String> saveCartToDb(@RequestBody List<CartItem> cartItemList, Principal principal){
        System.out.println(cartItemList);
        User logedInUser = userService.findUserByUsername(principal.getName()).get();

        List<CartItem> cartItem = logedInUser.getCartProduct();
        if(cartItem.isEmpty()){
            logedInUser.setCartProduct(cartItemList);
            userService.saveNewUser(logedInUser);
        }else {
            cartItem = cartItemList;
            logedInUser.setCartProduct(cartItem);
            userService.saveNewUser(logedInUser);
        }
//        userService.saveNewUser(logedInUser);
        return ResponseEntity.ok().body("ASD");
    }

如何覆盖< code >列表的内容

我也尝试过如何使用sping-data-jpa更新实体?但我不确定是否需要为此问题创建@Query。


共有1个答案

荀学文
2023-03-14

我设法让它工作。解决方案如下。

这是一个双向一对多/多对一的问题。为了能够从父元素中删除子元素,我们需要将它们与父元素解耦(分离)。由于父项和子项通过外键绑定在一起,因此必须在两端完成分离。如果一个引用另一个,这将不起作用,因此必须删除两个引用。需要 2 个方法,在进行解耦时都需要调用这两种方法。这就是我使用的。

private Set<CartProduct> cartProduct;

这个要添加到父类(用户)中。

 public void removeChild(CartProduct child) {
        this.cartProduct.remove(child);
    }

这个要在儿童类中添加

  public void removeParent() {
        this.user.removeChild(this);
        this.user = null;
    }

方法也必须这样调用

   for(CartProduct cartItem : cartItemList){
                cartItem.removeParent();
                logedInUser.removeChild(cartItem);
            }

五十、 电子

通过上面的实现,您可能会得到一个

java.util.ConcurrentModificationException: null

这件事在我身上也发生过。为了解决这个问题,我使用了一个像下面这样的迭代器。

for (Iterator<CartProduct> iterator = cartItemList.iterator(); iterator.hasNext();) {
                CartProduct cartItem = iterator.next();
                if (cartItem != null) {  
                    iterator.remove();
                }
            }
 类似资料:
  • 问题内容: 我有一个简单的测试,尝试在其中更新对象,但是合并似乎在执行插入操作而不是更新操作。 } 这是我的更新方法 更新代码 现在,我收到以下错误无法提交JPA事务;嵌套的异常是javax.persistence.RollbackException:标记为rollbackOnly的事务 问题答案: 我有一个版本列,当种子数据插入数据库时​​未设置该列。因此,所有有关更新和删除的问题

  • React没有合并我对状态对象所做的更改,而是完全覆盖它。 这可能是由上下文引起的吗?我不确定是否可以直接作为道具传递分派事件。我尝试过在另一个函数中包装,比如在“提升状态”文档中,但是没有效果。 预期产量 电流输出 React上下文保存状态 通用输入组件

  • 嗨,我是Spring Data JPA的新手,我想知道即使我将Id传递给实体,Spring data jpa也是插入而不是合并的。我想当我实现持久接口并实现这两个方法时: 它将自动合并而不是持久化。 我有一个名为User like的实体类: 再上一节课 我有一个名为UserRepostory的自定义存储库,它扩展了JpaReopistory。当我看到实现演示SpringDataJpa使用以上两种方

  • 问题内容: 我正在使用org.hibernate.cfg.ImprovedNamingStrategy,但是对于表我已经明确指定了表名 但是hibernate似乎正在寻找event_log。显式命名不应该覆盖EnhancedNamingStrategy提供的命名 问题答案: 这是org.hibernate.cfg.ImprovedNamingStrategy的行为,它将混合大小写的名称转换为嵌入的

  • 我使用,但这给我带来了partitionBy和intsertInto不能同时使用的问题。