首页 > 解决方案 > 如何使用 Spring Data JPA 更新实体中的集合字段?

问题描述

假设我有两个实体,它们的字段之间有 @ManyToMany 关系。第一个名为Pack的实体:

@ManyToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
    @JoinTable(name = "card_in_pack",
            joinColumns = {@JoinColumn(name = "pack_id")},
            inverseJoinColumns = {@JoinColumn(name = "card_id")})
    private Set<Card> cards = new HashSet<>();

第二个叫Card

@ManyToMany(mappedBy = "cards")
private Set<Pack> packs = new HashSet<>();

我有一个控制器,我想在其中将新的 Card实体添加到Pack实体中的集合中,然后我想将其全部保存到我的数据库中,当然还有关系。

@PostMapping("/packs/{namePack}")
    public String addCard(@Valid Card card, @PathVariable String namePack, @AuthenticationPrincipal User user) {
            //Assume I got a Pack instance with name pack

            card.setAuthor(user);
            pack.addCard(card);
            packRepo.save(pack);

            return "pack";
        }
    }

看起来每次我尝试调用packRepo.save(pack)方法时,它都会获取 Pack 实体中的所有 Card 实体并将它们作为新实体保存到数据库中,即使其中一些已经存在于我的数据库中. 我希望它检查 Pack 实体是否有一组卡片实体,它应该检查数据库中是否已经存在具有此类 ID 的每张卡片,并且只添加新卡片。我尝试清除集合,然后只添加我想要保存的新元素,但随后它只是从数据库中删除了所有不在当前包状态的内容并只添加新元素


我想要保存 @ManyToMany 相关 Set 的最好方法,这样它就不会在我的数据库中创建新的重复实例

标签: javahibernatespring-bootspring-data-jpamany-to-many

解决方案


我拿到包的方式真的很糟糕,我什至不会给你看)

有帮助的是:将所有存储库逻辑从控制器移动到服务,并用 @transactional 注释标记它!


推荐阅读