Spring Boot ManyToMany - *** - JPA,Hibernate

Posted

技术标签:

【中文标题】Spring Boot ManyToMany - *** - JPA,Hibernate【英文标题】:Spring Boot ManyToMany - *** - JPA,Hibernate 【发布时间】:2020-02-04 14:41:00 【问题描述】:

在我的 Spring Boot 应用程序中,我有一个名为 User 的类:

@Data
@Entity
public class User 
    @Id
    Long userID;
    ...
    @ManyToMany(mappedBy = "admins")
    private List<ClassRoom> classRooms  = new ArrayList<>();

我还有另一个名为 ClassRoom 的课程:

@Data
@Entity
public class ClassRoom 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    Long classRoomID;
    ...
    @ManyToMany
    @JoinTable(name ="clas-s-room_admins",
            joinColumns = @JoinColumn(name = "clas-s-room_id"),
            inverseJoinColumns = @JoinColumn(name = "user_id"))
    private List<User> admins = new ArrayList<>();

在我的ClassRoomController 我有一个这样的方法:

@PostMapping("/class")
ClassRoom newClassRoom(@RequestBody User user) 
    ClassRoom classRoom=new ClassRoom();
    classRoom.getAdmins().add(user);
    user.getClassRooms().add(classRoom);
    logger.debug(classRoom);
    logger.debug(user);
    return repository.save(classRoom);

现在我发布了curl -X POST -H "Content-Type: application/json" -d " \"userID\":\"22\" " http://localhost:8080/class

这个请求给了我错误,说:java.lang.***Error

我应该使用ToString.Exclude | JsonBackReference | @JsonManagedReference 或类似的东西,不确定,哪个是正确的,最好的,我应该使用哪个?

在我的UserController

@PostMapping("user/id/c")
User addClassRoom(@PathVariable Long id,@RequestBody ClassRoom newClassRoom)

    logger.debug(repository.findById(id));
    return repository.findById(id)
            .map(user -> 
                user.getClassRooms().add(newClassRoom);
                newClassRoom.getAdmins().add(user);
                return repository.save(user);
            )
            .orElseGet(() -> 
                return null;
            );

我发布了这个curl -X POST -H "Content-Type: application/json" -d " " http://localhost:8080/user/2/c

这在 ClassRoom 中创建了一个条目,但 User[] ClassRoomClassRoom[] adminsCLAs-s-rOOM_USER 表也是空的。

我该如何解决这个问题?

完整的控制台here。

【问题讨论】:

@buræquete 你有答案吗?你能帮帮我吗? 抱歉我才看到你的邮件,今天还有问题吗? 【参考方案1】:
ClassRoom classRoom = new ClassRoom();
classRoom.getAdmins().add(user);
return repository.save(classRoom);

不要为用户设置 classRooms。它将被自动分配。

反之亦然,基本上只做一项分配,因为 Hibernate 将处理表中的多对多关系数据。

【讨论】:

"org.hibernate.TransientObjectException:对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例:com.mua.cse616.Model.User;嵌套异常是 java.lang.IllegalStateException: org .hibernate.TransientObjectException: 对象引用了一个未保存的瞬态实例 - 在刷新之前保存瞬态实例:com.mua .cse616.Model.User", - 现在我有了这个 为教室设置@ManyToMany(cascade=CascadeType.ALL) "尝试从空的一对一属性 [com.mua.cse616.Model.User.loginCredential] 分配 id;嵌套异常是 org.hibernate.id.IdentifierGenerationException:尝试分配id from null 一对一属性 [com.mua.cse616.Model.User.loginCredential]" - 新错误 可能是 @GeneratedValue(strategy = GenerationType.AUTO) 到 User.userId? UseruserID 来自一个名为LoginCredential 的类,现在?【参考方案2】:

教室有现场管理员(列表),每个用户都有现场教室。 教室加载用户和用户加载教室所以发生 ***Error。 你必须在管理员字段的用户类中使用像 @JsonIgnore 注释这样的 somting。

【讨论】:

欢迎。如果我使用@JsonIgnore,我将如何通过我的 rest-api 访问那些? 你的一个实体必须看到另一个。如果你想让他们两个互相访问,你必须使用 DTO,其中一个有列表,另一个没有列表。例如 UserDTO 有 List 而 UserLightDTO 没有。课堂实体的反向 那么该怎么做呢?你能帮我写代码吗? 因为我从未听说过 DTO.. 查看此链接thoughts-on-java.org/dto-projections。许多工具都可以为您做到这一点,例如 mapstruct 或 modelmapper

以上是关于Spring Boot ManyToMany - *** - JPA,Hibernate的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot 无法评估表达式方法抛出 'org.hibernate.LazyInitializationException' 异常。使用 getter,ManyToMany 关系

Json Result 在 ManyToMany 中有重复项,在 Spring Boot 中有一个新实体

Spring Boot 和事务边界

具有 MySql ManyToMany 关系的 Spring Boot 无法持久保存到数据库,说“java.sql.SQLException:SQL 字符串不能为 NULL”

如何使用 @ManyToMany 审核 @JoinTable

Spring-boot JPA无限循环多对多