0

作業中のプロジェクトを Spring2+Hibernate3 から Spring3+Hibernate4 にアップグレードしています。HibernateTemplate と HibernateDAOSupport が廃止されたので、次のようにしました。

前(簡略化)

public List<Object> loadTable(final Class<?> cls)
{
    Session s = getSession(); // was calling the old Spring getSession
    Criteria c = s.createCriteria(cls);
    List<Object> objects = c.list();
    if (objects == null)
    {
        objects = new ArrayList<Object>();
    }
    closeSession(s);
    return objects;
}

現在(簡略化)

@Transactional(propagation=Propagation.REQUIRED)
public List<Object> loadTable(final Class<?> cls)
{
    Session s = sessionFactory.getCurrentSession();
    Criteria c = s.createCriteria(cls);
    List<Object> objects = c.list();
    if (objects == null)
    {
        objects = new ArrayList<Object>();
    }
    return objects;
}

また、トランザクション アノテーション宣言を Spring XML に追加し、これを Hibernate プロパティから削除しました。

 "hibernate.current_session_context_class", "org.hibernate.context.ThreadLocalSessionContext"

スタックトレースでこれを見ると、 @Transactional アノテーションが機能しているようです

at com.database.spring.DatabaseDAOImpl$$EnhancerByCGLIB$$7d20ef95.loadTable(<generated>)

初期化中、上記の変更は loadTable 関数へのいくつかの呼び出しで機能するように見えますが、親を持つエンティティをロードするようになると、「cascade="all-delete-orphan を持つコレクション」が参照されなくなりました" エラー。親または子を設定/取得する他のコードには触れておらず、DAOメソッドを修正しようとしているだけで、クエリはSQL SELECTのみを実行しているため、コードが壊れた理由を誰でも見ることができますか?

この問題は、 Spring のトランザクション管理が休止状態のカスケードを破るに似ているようです

4

2 に答える 2

0

問題はセッション管理にありました。トランザクション コードの同じブロックが、独自のセッション処理を行っている他のモジュールによって呼び出されていました。さらに困ったことに、呼び出しモジュールの一部は Spring Bean でしたが、他のモジュールは直接の Hibernate API スタイルで書かれていました。この混乱は、私たちがすぐに Hibernate 4 に移行しないようにするのに十分な作業でした。

教訓 (その英語はどうですか?): プロジェクト全体で一貫した DAO 実装を使用し、明確に定義されたセッションおよびトランザクション管理戦略に固執します。

于 2013-06-25T22:16:38.397 に答える
0

これはSpringの問題ではなく、エンティティの処理/定義の問題です。deleteOrphansリレーションで使用している場合、基になるものをエンティティ自体から削除してはPersistentSet なりません。セット インスタンス自体の変更のみが許可されます。したがって、エンティティ セッター内で巧妙なことをしようとしている場合は、それが原因です。

また、私が覚えている限りdeleteOrphans、リレーションの両側にある場合、および/または1つのセッション内で両側をロード/操作する場合、いくつかの問題があります。


ところで。必要ないと思います"hibernate.current_session_context_class", "org.hibernate.context.ThreadLocalSessionContext"。私たちのプロジェクトでは、これが唯一の構成です。

@Bean
public LocalSessionFactoryBuilder sessionFactoryBuilder() {
    return ((LocalSessionFactoryBuilder) new LocalSessionFactoryBuilder(
            dataSourceConfig.dataSource()).scanPackages(ENTITY_PACKAGES).
            setProperty("hibernate.id.new_generator_mappings", "true").
            setProperty("hibernate.dialect", dataSourceConfig.dialect()).
            setProperty("javax.persistence.validation.mode", "none"));
}

@Bean
public SessionFactory sessionFactory() {
    return sessionFactoryBuilder().buildSessionFactory();
}
于 2013-06-15T08:58:00.490 に答える