Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPA-@PreRemove方法行为_Java_Hibernate_Jpa - Fatal编程技术网

Java JPA-@PreRemove方法行为

Java JPA-@PreRemove方法行为,java,hibernate,jpa,Java,Hibernate,Jpa,我有两个具有多对多关系的实体。电影实体是这个关系的所有者,所以当我想要删除一个演员实体时,我会使用一个注释为@PreRemove的方法来删除电影播放中出现的演员ID,以避免“外键冲突异常” 电影类 @Entity public class Movie extends AbstractBusinessObject{ @ManyToMany private Map<String, Actor> cast; // setters and getters

我有两个具有多对多关系的实体。电影实体是这个关系的所有者,所以当我想要删除一个演员实体时,我会使用一个注释为@PreRemove的方法来删除电影播放中出现的演员ID,以避免“外键冲突异常”

电影类

@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);
        }
    }

}
@实体
公共类电影扩展了AbstractBusinessObject{
@许多
私人地图播送;
//二传手和接球手
public void removeCastMember(参与者){
对于(条目e:cast.entrySet()){
if(e.getValue().id.equals(actor.id)){
cast.remove(例如getKey());
}
}
}//removeCastMember()
}
演员班

@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);
        }
    }

}
@实体
公共类参与者扩展了AbstractBusinessObject{
@许多(mappedBy=“cast”)
私人电影;
//二传手和接球手
@预移除
private void removeActorFromMovies(){
电影(m:电影){
m、 removeCastMember(本);
}
}
}

需要说明的是,通过我的测试,它可以正常工作-在数据库中正确更新电影对象。但是,我无法理解在没有调用saveOrUpdate()或持久化/合并这些对象的情况下,这是怎么可能的。

这是JPA/Hibernate的一个基本功能。对附加实体所做的所有更改都会自动持久化:Hibernate管理它们,因此它会将它们的当前状态与初始状态进行比较,并自动使所有更改持久化

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

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

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管理


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

感谢您的详细回答。我真的忘记了重要的部分:
merge用于获取分离的实体