【问题标题】:Spring Boot ManyToMany - StackOverflow - JPA,HibernateSpring Boot ManyToMany - StackOverflow - 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 ="classroom_admins",
            joinColumns = @JoinColumn(name = "classroom_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.StackOverflowError

我应该使用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[] adminsCLASSROOM_USER 表也是空的。

我该如何解决这个问题?

完整的控制台here

【问题讨论】:

  • @buræquete 你有答案吗?你能帮帮我吗?
  • 抱歉我才看到你的邮件,今天还有问题吗?

标签: spring spring-boot jpa spring-data-jpa many-to-many


【解决方案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】:

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

【讨论】:

  • 欢迎。如果我使用@JsonIgnore,我将如何通过我的 rest-api 访问那些?
  • 你的一个实体必须看到另一个。如果你想让他们两个互相访问,你必须使用 DTO,其中一个有列表,另一个没有列表。例如 UserDTO 有 List 而 UserLightDTO 没有。课堂实体的反向
  • 那么该怎么做呢?你能帮我写代码吗? 因为我从未听说过 DTO..
  • 查看此链接thoughts-on-java.org/dto-projections。许多工具都可以为您做到这一点,例如 mapstruct 或 modelmapper
猜你喜欢
  • 2020-07-20
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
  • 2016-03-08
  • 1970-01-01
  • 1970-01-01
  • 2021-11-06
  • 2019-06-16
相关资源
最近更新 更多