JPA-@PreRemove方法行为 [英] JPA - @PreRemove method behaviour

查看:247
本文介绍了JPA-@PreRemove方法行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个具有多对多关系的实体.电影实体是该关系的所有者,因此,当我想删除演员实体时,我使用一种注解@PreRemove的方法来删除电影演员中所有出现的演员ID,以避免出现外键违反异常".

I have 2 entities with many-to-many relationship. The Movie Entity is the owner of this relation, so when I want to delete an Actor Entity I use a method annotated @PreRemove to delete any occurrences of Actor ID in Movie cast to avoid "Foreign key violation exception".

电影课

@Entity
public class Movie extends AbstractBusinessObject{

    @ManyToMany
    private Map<String, Actor> cast;

    // setters and getters

    public void removeCastMember(Actor actor){

        for (Entry<String, Actor> e : cast.entrySet()) {
            if(e.getValue().id.equals(actor.id)){
                cast.remove(e.getKey());
            }
        }

    } // removeCastMember()

}

演员班

@Entity
public class Actor extends AbstractBusinessObject{

    @ManyToMany(mappedBy = "cast")
    private Set<Movie> movies;

    // setters and getters

    @PreRemove
    private void removeActorFromMovies() {
        for (Movie m : movies) {
            m.removeCastMember(this);
        }
    }

}

为清楚起见,根据我的测试,可以正常工作-电影对象在数据库中已正确更新.但是,我不明白在没有调用saveOrUpdate()或持久化/合并这些对象时怎么可能.

To be clear, from my testing, it works - movie objects are correctly updated in the database. However, I cannot understand how is it possible when there are no calls to saveOrUpdate() or persist/merge those objects.

推荐答案

这是JPA/Hibernate的基本功能.对连接的实体所做的所有更改都将自动持久化:Hibernate对其进行管理,因此将其当前状态与初始状态进行比较,并自动使所有更改持久化.

That's a fundamental feature of JPA/Hibernate. All the changes made to attached entities are automatically made persistent: Hibernate manages them, so it compares their current state with their initial state, and automatically makes all the changes persistent.

这非常有用,因为您不必跟踪在修改大量实体的复杂业务方法中已修改的所有实体.而且它也是有效的,因为Hibernate不会执行不必​​要的SQL:如果在事务期间没有更改实体,则不会对该实体执行任何SQL更新查询.而且,如果您修改实体,然后在回滚事务时引发异常,则Hibernate将跳过更新.

This is extremely useful, because you don't have to track all the entities that have been modified in a complex business method modifying lots of entities. And it's also efficient because Hibernate won't execute unnecessary SQL: if an entity hasn't changed during the transaction, no SQL update query will be executed for this entity. And if you modify entities and then throw an exception rollbacking the transaction, Hibernate will skip the updates.

因此,典型的JPA代码如下所示:

So, typical JPA code would look like this:

void transfer(Long fromAccountId, Long toAccountId, BigDecimal amount) {
    Account from = em.find(Account.class, fromAccountId); // from is managed by JPA
    Account to = em.find(Account.class, ftoAccountId); // to is managed by JPA
    from.remove(amount);
    to.add(amount);

    // now the transaction ends, Hibernate sees that the state of from and to 
    // has changed, and it saves the entities automatically before the commit
}

persist()用于使新实体持久化,即使其由Hibernate管理.

persist() is used to make a new entity persistent, i.e. to make it managed by Hibernate.

merge()用于获取一个分离的实体(即不受Hibernate管理但已具有ID和状态的实体)并将其状态复制到具有相同ID的附加实体.

merge() is used to take a detached entity (i.e. an entity which is not managed by Hibernate, but already has an ID and a state) and to copy its state to the attached entity having the same ID.

这篇关于JPA-@PreRemove方法行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆