首页 > 解决方案 > M:N 表不更新

问题描述

我在用户和文档之间有 m:n 关系。我正在创建 Document 对象,获取 List - setDocumentsForUsers() 然后我正在持久化该对象。问题是,该文档是在我的数据库中创建的,但不是 M:N 关系。我究竟做错了什么?我在坚持后尝试调用flush,但它根本没有帮助。

@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(name = "first_name")
    private String firstName;
    private String surname;
    private String email;
    private String password;

    @ManyToMany
    @JoinTable(
            name = "users_roles",
            joinColumns = @JoinColumn(
                    name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(
                    name = "role_id", referencedColumnName = "id"))
    private List<Role> roles;

    @JsonIgnore
    @ManyToMany
    @JoinTable(
            name="users_documents",
            joinColumns = @JoinColumn(
                    name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(
                    name="document_id", referencedColumnName = "id"))
    private List<Document> usersDocuments;


    @OneToMany(mappedBy="user")
    private List<Document> sharedDocuments;


    public User() {

    }

    public User(String firstName, String surname, String email, String password) {
        this.firstName = firstName;
        this.surname = surname;
        this.email = email;
        this.password = password;
    }

    public void setId(long id) {
        this.id = id;
    }

    public long getId() {
        return id;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email){this.email = email;}

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public List<Role> getRoles() {
        return roles;
    }

    public List<Document> getUsersDocuments() {
        return usersDocuments;
    }

    public void setUsersDocuments(List<Document> usersDocuments) {
        this.usersDocuments = usersDocuments;
    }

    public List<Document> getSharedDocuments() {
        return sharedDocuments;
    }

    public void setSharedDocuments(List<Document> sharedDocuments) {
        this.sharedDocuments = sharedDocuments;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof User)) return false;
        User user = (User) o;
        return getId() == user.getId();
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId());
    }

    @Override
    public String toString() {
        return "User{" +
                "firstName='" + firstName + '\'' +
                ", surname='" + surname + '\'' +
                ", email='" + email + '\'' +
                ", roles=" + roles +
                '}';
    }
}

我的文档类:

@Entity
public class Document {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Column(unique = true)
    private String name;

    private String title;

    private String description;

    @Column(name = "resource_path")
    private String resourcePath;

    @Column(name = "upload_datetime", columnDefinition = "DATETIME")
    @Temporal(TemporalType.TIMESTAMP)
    private Date uploadDatetime;

    @ManyToMany(mappedBy = "usersDocuments")
    private List<User> documentsForUsers;

    @ManyToOne
    @JoinColumn(name="user_id", nullable=false)
    private User user;


    public Document() {

    }

    public Document(String title, String description){
        this.title = title;
        this.description = description;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getResourcePath() {
        return resourcePath;
    }

    public void setResourcePath(String resourcePath) {
        this.resourcePath = resourcePath;
    }


    @Override
    public String toString() {
        return "Document{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", description='" + description + '\'' +
                ", resourcePath='" + resourcePath + '\'' +
                ", uploadDatetime=" + uploadDatetime + '\'' +
                ". user=" + user;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Document)) return false;
        Document document = (Document) o;
        return getId() == document.getId();
    }

    @Override
    public int hashCode() {
        return Objects.hash(getId());
    }

    public Date getUploadDatetime() {
        return uploadDatetime;
    }

    public void setUploadDatetime(Date uploadDatetime) {
   //     Date startDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse(uploadDatetime.toString());
        this.uploadDatetime = uploadDatetime;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public List<User> getDocumentsForUsers() {
        return documentsForUsers;
    }

    public void setDocumentsForUsers(List<User> documentsForUsers) {
        this.documentsForUsers = documentsForUsers;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

执行此操作:

Optional<User> user = userService.getUserByEmail(createdBy);
        Document document = new Document(title, desc);
        document.setUploadDatetime(new Date());
        document.setUser(user.get());

        List<User> users = userService.getUsersByRoles(roles);

        document.setDocumentsForUsers(users);
        saveDocument(document);


@Override
    public void saveDocument(Document document) {
        entityManager.persist(document);
    }

标签: javaspringhibernatejpa

解决方案


您的班级用户是关系@ManyToMany的所有者

List<Document> usersDocuments;

因为用户@JoinTable文档类是一个Inverse end。如果一个文档被持久化,那么一个数据将被保存而没有关系。因为 Inverse end 只关心自己,不关心关系。

默认情况下,您只能从所有者方保留关系。

在我测试的情况下,为了能够从相反的一端保持关系,那么在你的情况下:

  1. 在文档中添加级联:
@ManyToMany(cascade = CascadeType.PERSIST, mappedBy = "usersDocuments")
private List<User> documentsForUsers;

并在您的设置器中添加一个新代码:

public void setDocumentsForUsers(List<User> documentsForUsers) {
    if (documentsForUsers != null){
        documentsForUsers.forEach(u -> {
            u.getUsersDocuments().add(this); //here you should have not-null list u.getUsersDocuments()
        });
    }
    this.documentsForUsers = documentsForUsers;
}
  1. 在用户类中添加级联:
@ManyToMany(cascade = CascadeType.PERSIST)

private List<Document> usersDocuments = new ArrayList<>();

推荐阅读