使用manytomany集合删除对象

时间:2017-05-12 10:59:50

标签: java jpa persistence

Sitiuation:试图移除拥有一群人(朋友)的人。当然我不希望朋友被删除所以我必须小心。

人员代码:

@Entity
public class Person {

private String naam, voornaam, email, password;

@Id
private String username;
private String status;

@ManyToMany
private Collection<Person> vrienden;

@OneToMany(orphanRemoval = true)
private Collection<Post> posts;

@Enumerated(EnumType.STRING)
private Role role;

public Person(String naam, String voornaam, String email, String password, String username) {
    setNaam(naam);
    setEmail(email);
    setStatus("online");
    setVoornaam(voornaam);
    setPassword(password);
    setUsername(username);
    vrienden = new HashSet<>();
    posts = new HashSet<>();
    role = Role.USER;
}

public static void addFriend(Person a, Person b) {
    a.addFriend(b);
    b.addFriend(a);
}

private void addFriend(Person b) {
    this.vrienden.add(b);
}

public static void deleteFriend(Person a, Person b) {
    a.deleteFriend(b);
    b.deleteFriend(a);
}

private void deleteFriend(Person a) {
    this.vrienden.remove(a);
}

public Collection<Person> getFriends() {
    return vrienden;
}

public Role getRole() {
    return this.role;
}

public void setRole(Role role) {
    this.role = role;
}

@NotNull(message = "{error.no.name}")
@Size(min = 2, message = "{error.invalid.namesize}")
public String getNaam() {
    return naam;
}

public void setNaam(String naam) {

    this.naam = naam;
}

@NotNull(message = "{error.no.surnaam}")
@Size(min = 2, message = "{error.invalid.surnamesize}")
public String getVoornaam() {
    return voornaam;
}

public void setVoornaam(String voornaam) {

    this.voornaam = voornaam;
}

@NotNull(message = "{error.no.email}")
@Email(message = "{error.invalid.email}")
public String getEmail() {
    return email;
}

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

@NotNull(message = "{error.no.status}")
@Size(min = 1, message = "{error.no.valid.status}")
public String getStatus() {
    return status;
}

public void setStatus(String status) {

    this.status = status;
}

@NotNull(message = "{error.no.username}")
@Size(min = 2, message = "{error.invalid.usernamesize}")
public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

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

public boolean isPasswordCorrect(String password) {
    boolean result = false;
        result = Password.check(password, this.password);      
    return result;
}

@NotNull(message = "{error.no.password}")
@Size(min = 2, message = "{error.invalid.usernamesize}")
public String getPassword() {
    return this.password;
}



public void addPost(Post p) {
    if (p == null) {
        throw new DomainException("Post is null");
    }
    posts.add(p);
}

public void deletePost(Post p) {
    if (p == null) {
        throw new DomainException("Post is null");
    }
    posts.remove(p);
}

public Collection<Post> getPosts() {
    return posts;
}

@Override
public int hashCode() {
    int hash = 3;
    hash = 59 * hash + Objects.hashCode(this.username);
    return hash;
}

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

}

我目前使用的方法是:

   public void DeletePerson(String user) {
    entityManager.getTransaction().begin();
    entityManager.createQuery("delete from Person p where p.username=:username").setParameter("username", user).executeUpdate();
    entityManager.getTransaction().commit();
}

它出现以下错误:

  

java.sql.SQLIntegrityConstraintViolationException:表'PERSON'上的DELETE导致密钥(vincent)违反外键约束'PRSNPRSNVRNDNSRNME'。声明已经回滚。

我的猜测是在manytomany注释中添加一些内容

创建表格:  https://i.stack.imgur.com/zS2Xf.png

更新:

我现在用来成功删除的代码:

public void DeletePerson(String user) {
    entityManager.getTransaction().begin();
    entityManager.createNativeQuery("delete from PERSON_PERSON p where p.PERSON_USERNAME=?username or p.VRIENDEN_USERNAME=?username").setParameter("username", user).executeUpdate();
    entityManager.flush();
    Person tempPerson = getPerson(user);
    entityManager.remove(tempPerson);
    entityManager.getTransaction().commit();

}

但是现在我仍然检索旧的引用,尽管表中删除了数据。我用以下方法检索数据:

entityManager.find(Person.class, user);

2 个答案:

答案 0 :(得分:0)

你需要首先删除所有帖子和vrienden(关系 - 可能是一些中间表)然后删除当前人员(因为外键约束不允许你这样做 - 因为来自不同表的许多其他行可能依赖于此表。

https://stackoverflow.com/a/1089008/5284920

答案 1 :(得分:0)

您不能删除在另一个人的列表中作为朋友存在的人。首先,您应该将其从其他人对象(db中的行)中的所有好友列表(vrienden)中删除,然后将其删除。错误消息清楚地表明您无法删除行,因为该记录在其他表中是FK。