使用 Spring JPA 的单向多对多映射

Posted

技术标签:

【中文标题】使用 Spring JPA 的单向多对多映射【英文标题】:Unidirectional ManyToMany mapping using Spring JPA 【发布时间】:2019-01-08 19:56:07 【问题描述】:

在我的项目中,我希望有 ManyToMany 单向映射。为此,我为它们创建了 User 和 Recipe 实体和存储库(使用 Spring JPA 存储库)。现在我想用一些示例条目填充我的数据库。一旦我启动 spring-boot 应用程序,就会发生错误:

org.hibernate.PersistentObjectException:分离的实体传递给 坚持:com.example.demo.database.Recipe

这是我的 User 和 Recipe 类:

-- 用户--

@Data
@Entity
public class User 

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

    @NotNull
    private String email;

    @NotNull
    @Size(min = 8)
    private String password;

    @ManyToMany(cascade = CascadeType.ALL)
    private Set<Recipe> favouriteRecipes = new HashSet<>();

    private User() 

    public User(String email, String password) 
        this.email = email;
        this.password = password;
    

-- 配方--

@Data
@Entity
public class Recipe 

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

    @NotNull
    private String title;

    private Recipe() 

    public Recipe(String title) 
        this.title = title;
    


这是我如何将行添加到数据库:

@Component
public class DatabaseInitializer implements CommandLineRunner 

    @Autowired
    private UserRepository userRepository;

    @Override
    public void run(String... args) throws Exception 
        User u1 = new User("rick.astley@gmail.com", "admin123");
        User u2 = new User("john.doe@gmail.com", "admin123");

        Recipe r1 = new Recipe("Chicken curry");
        Recipe r2 = new Recipe("Spaghetti bolognese");

        u1.getFavouriteRecipes().add(r1);
        u1.getFavouriteRecipes().add(r2);

        u2.getFavouriteRecipes().add(r1);
        u2.getFavouriteRecipes().add(r2);

        userRepository.save(u1);
        userRepository.save(u2);

    

我尝试遵循 this 教程,但是那里的人使用休眠而不是 Spring 存储库,所以这就是我被困在这里的原因。我真的不知道我错在哪里。

任何帮助将不胜感激:)

【问题讨论】:

它告诉您的是先保存Recipe,然后再将其添加到User 实体。 @ObiWan-PallavJha 你是对的,但是用户类中的级联应该为我做这件事,不是吗? 【参考方案1】:

当您保存User u2 时,Hibernate 会尝试再次保存Recipes r1 and r2(因为它在保存User u1 时已经保存了它)。这是因为 @ManyToMany 注释存在于 User 类中,如 User 似乎是 Recipe 的父级,而 Recipies 可能在 Users 之间是常见的。

解决方案:

    从注释中删除cascade

&

    先保存食谱,然后将它们添加到favoriteRecipe 集合中。

以下链接可能会有所帮助:

A beginner’s guide to JPA and Hibernate Cascade Types

How to persist @ManyToMany relation - duplicate entry or detached entity

【讨论】:

以上是关于使用 Spring JPA 的单向多对多映射的主要内容,如果未能解决你的问题,请参考以下文章

Jpa之关联对象(单向多对多)

hibernate的映射之三(多对多单向关联)

Hibernate之关于多对多单向关联映射

多对多 Spring Boot JPA 未填充多对多表

使用 JPA 映射与属性的多对多关系

JPA多对多映射