Удаляет ли Hibernate ссылочные объекты при вызове entityManager.remove ()? - PullRequest
2 голосов
/ 10 марта 2012

У меня следующая (упрощенная) проблема:

У меня есть сущность в отношениях «многие к одному»:

@Entity
public class Membership {

    private User user;

    @ManyToOne(cascade = CascadeType.ALL)
    public User getUser() {
        return user;
    }

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

}

... и следующий соответствующий класс на стороне «один ко многим»:

@Entity
public class User extends Person {
    private Set<Membership> memberships = new HashSet<Membership>();

    @OneToMany(mappedBy = "user", cascade = { CascadeType.MERGE,
            CascadeType.REMOVE, CascadeType.REFRESH })
    public Set<Membership> getMemberships() {
        return memberships;
    }

    public void setMemberships(Set<Membership> memberships) {
        this.memberships = memberships;
    }
}

Я создал пользователя с именем user1 и членство mem1 через new и связал его так:

mem1.setUser(user1);
user1.getMemberships().add(mem1);

тогда я сохраняю их так:

entityManager.getTransaction().begin();
entityManager.persist(user1);
entityManager.persist(mem1);
entityManager.getTransaction().commit();

Теперь я хочу удалить членство. Поэтому я звоню:

entityManager.remove(mem1);

... напомним, что я установил cascade=CascadeType.REMOVE на стороне User и cascade=CascadeType.ALL на стороне Membership. Но указанное членство mem1 не удаляется из user1 автоматически, то есть user1.getMemberships() все еще удерживает mem1! Это правильное поведение? JPA никогда не удаляет ссылки автоматически из объектов при удалении сущностей из базы данных?

Это может показаться глупым вопросом, но я новичок в JPA, и иногда трудно точно понять, какую магию аннотации будут выполнять для вас, потому что иногда это довольно много.

Ответы [ 2 ]

3 голосов
/ 10 марта 2012

Каскадное удаление приведет к вызову Hibernate entityManager.remove() для объекта, на который имеется ссылка (или набора объектов). Таким образом, указанная сущность будет удалена из базы данных. Но это оставляет экземпляры сущности нетронутыми.

Обратите внимание, что наличие каскада = REMOVE (или ALL) на ManyToOne обычно является очень плохой идеей. Обычно вы не хотите удалять пользователя при удалении только одного из его участников.

2 голосов
/ 10 марта 2012

Ну да, в этом случае это не очень хорошо работает.Из-за того, что ваши связанные сущности могут быть отсоединены или нет, чтобы убедиться, что вы удалили их, вы можете сделать одну из двух вещей:

  • , если вы используете JPA2, добавьте orphanRemoveопция:

    @ OneToMany (mappedBy = "что угодно", orphanRemoval = true)

  • если вы используете JPA1, вы должны удалить их вручную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...