12

多対多の関係を持つ 2 つのエンティティがあります。映画エンティティはこの関係の所有者であるため、俳優エンティティを削除する場合は、@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);
        }
    }

}

明確にするために、私のテストから、それは機能します-映画オブジェクトはデータベースで正しく更新されます。ただし、 saveOrUpdate() への呼び出しがない場合、またはそれらのオブジェクトを永続化/マージしない場合に、どのように可能になるのか理解できません。

4

1 に答える 1

17

これは、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 を持つ添付されたエンティティにコピーするために使用されます。

于 2013-11-03T09:40:35.747 に答える