2012-02-28 4 views
2

別のエンティティ(CoverArt)への@OneToManyマッピングを持つエンティティクラス(Song)を持ち、カスケードをALLに設定すると、私はちょうど取得し、データベースからクラスのインスタンスと、セッション内だけで変更した場合、メインentiyを保存し、それがカバーアートCascadeType.ALLを使用している場合、Hibernateでトップエンティティを保存すると、関係するエンティティにuneccssaryアップデートが発生します

@Audited 
@Entity 
public class Song 
{ 
    @Id 
    @GeneratedValue 
    private Integer recNo; 

    @Version 
    private int version; 

    @OneToMany(fetch = FetchType.EAGER, cascade = {CascadeType.ALL}) 
    private List<CoverArt> coverArts; 

    .... 

} 

を永続化するの世話をしましょう。しかし、私は、コードの後の時点で発見しますカバーアートのために何も変わっていないにもかかわらず、その曲にリンクされたすべてのカバーアートエンティティを更新させるソングエンティティの1つのフィールドは、なぜこれを行うのですか?

また、私はEnversを使用していると思いますが、CoverArtテーブルへの(一見)不必要な追加アップデートはEnversに不必要な監査テーブルを作成させるノックの影響を与えます。

カスケードタイプのアノテーションを削除しても、1つのフィールドを変更してもカバーアートエンティティが更新されることはなく、カバーアートを追加するときに余分なロジックを追加しても問題ありませんが、これを行う必要はありません。

+0

あなたは何とかcoverArtsコレクションのインスタンスを変更できますか?休止状態がチェンジトラッキングを失う可能性があります。また、CoverArtがSongへの逆参照を持っている場合は、@OneToManyにinverse = trueを設定する方が良いです。 – Firo

+0

それはどういう意味ですか、カバーアートを変更しません。逆参照はありません。 –

+0

Hibernateは何とかCoverArtsが変更されたと考えています。フィールドへのHibernateコレクションのセットが交換された場合、または何らかの方法で変更されたためにすべてのプロパティの値が等しくない場合は、親への参照です。実際に変更されているフィールドを表示するには、dynamicupdate = trueをCoverArtに設定します。 – Firo

答えて

1

私は新しいセッションを作成し、既存のセッションのメソッドを渡すのではなくDBから何かを取得するときにいつでもそれを閉じるというアンチパターンを使用していた問題を修正したようでした。オブジェクトで終了しましたが、これを修正することで問題は解決しました。

1

私は自分のアプリケーションに正確な問題があります。 私はcascade = {CascadeType.ALL}を使用して1対3を持っています

誰かが私に適切なセッション再利用の例を教えてもらえますか? マイコード:

public class HibernateUtil { 

private static final SessionFactory sessionFactory = buildSessionFactory(); 

private static SessionFactory buildSessionFactory() { 
    try { 
     // Create the SessionFactory from hibernate.cfg.xml 
     Configuration conf = new Configuration().configure(); 
     ServiceRegistry sr = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build(); 
     SessionFactory sf = conf.buildSessionFactory(sr); 
     return sf; 
    } 
    catch (HibernateException ex) { 
     // Make sure you log the exception, as it might be swallowed 
     System.err.println("Initial SessionFactory creation failed." + ex); 
     throw new ExceptionInInitializerError(ex); 
    } 
} 

public static SessionFactory getSessionFactory() { 
    return sessionFactory; 
} 

} 


public groupelti.lims.persistence.vo.LotEchantillonRegulier modifier(groupelti.lims.persistence.vo.LotEchantillonRegulier ler) throws DAOException { 

    // validation 
    if (ler == null) { 
     throw new IllegalArgumentException(); 
    } 
    if (ler.getId() == null) { 
     throw new IllegalArgumentException(); 
    } 
    if (ler.getId() <= 0) { 
     throw new IllegalArgumentException(); 
    } 

    // traitement 
    Session session = HibernateUtil.getSessionFactory().getCurrentSession(); 
    session.beginTransaction(); 

    try { 
     session.update(ler); 
     session.getTransaction().commit(); 
    } catch (PropertyValueException e) { 
     logger.info("" + e.getMessage()); 

     session.getTransaction().rollback(); 
     throw new DAOException("Voir log.", e); 
    } catch (ConstraintViolationException e) { 
     logger.info("" + e.getMessage()); 

     session.getTransaction().rollback(); 
     throw new DAOException("Voir log.", e); 
    } catch (GenericJDBCException e) { 
     logger.info("" + e.getMessage()); 

     session.getTransaction().rollback(); 
     throw new DAOException("Voir log.", e); 
    } catch (TransientObjectException e) { 
     logger.info("" + e.getMessage()); 

     session.getTransaction().rollback(); 
     throw new DAOException("Voir log.", e); 
    } finally { 
     try { 
      session.close(); 
     } catch (SessionException e) { 
      //do nothing 
     } 
    } 

    return ler; 
} 

接触[email protected] よろしく、マチュー

関連する問題