更新对象时Spring Boot多对一映射错误

时间:2019-02-03 15:16:33

标签: hibernate spring-boot jpa spring-data-jpa

我正在使用Spring Boot,并使用如下所示的多对一关系:

@Entity
@Table(name = "media_files")
public class Media {

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

  @OneToMany(mappedBy = "media", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval=true)
  private Set<MediaUser> users = new HashSet<>();

  ....

}

用户

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

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

  @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval=true)
 private Set<MediaUser> users = new HashSet<>();
 ....
}

MediaUser

@Entity
@Table(name = "media_to_users")
public class MediaUser implements Serializable {

   @Id
   @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
   @JoinColumn(name = "media_id")
   private Media media;

  @Id
  @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
  @JoinColumn(name = "user_id")
  private User user;


  @JsonBackReference
  @ManyToOne
  @JoinColumn(name = "parent_id")
  private Media parent;
  .....
 }

我会像这样添加新的条目

media.getUsers().add(new MediaUser(media, user, parent));

哪个可以正常工作,但是如果我尝试更新,则会报错

//Get media from db
Media media = mediaRepository.getOne(id);
//clear already existing entries
media.getUsers().clear();


   String[]  users = {"3","2"};
    for (String userIdStr: users) {
        User user = userRepository.getOne(Long.parseLong(userIdStr));
        if(user != null){
             media.getUsers().add(new MediaUser(media, user, null));
            //mediaUserSet.add(new MediaUser(media, user, null));
        }
    }

 mediaRepository.save(media);

错误是:

  java.sql.SQLIntegrityConstraintViolationException: Column 'user_id' cannot be null
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:117) ~[mysql-connector-java-8.0.13.jar:8.0.13]
    at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97) ~[mysql-connector-java-8.0.13.jar:8.0.13]

1 个答案:

答案 0 :(得分:0)

您很可能将user1, user2作为未持久的实体传递。

您需要在保存media之前保留它们,或在注释中添加级联:

 @Id
 @ManyToOne(cascade = CascadeType.ALL)
 @JoinColumn(name = "user_id")
 private User user;

您还需要确保如果User@OneToMayMediaUser关系,则必须将这些用户添加到集合中。

String[]  users = {"3","2"};
for (String userIdStr: users) {
    User user = userRepository.getOne(Long.parseLong(userIdStr));
    if(user != null){
        MediaUser mediaUser = new MediaUser(media, user, null) 
        user.getUsers().add(mediaUser);
        media.getUsers().add(mediaUser);
    }
}