3

Spring を使用して、MySQL データベースの永続化 API として Hibernate と JPA を使用してアプリケーションを開発しています。ほとんどのオブジェクトをデータベースから取得すると、オブジェクトの属性がデータベースの値で初期化され、コレクションが遅延ロードされます。この問題は、からusing メソッドBusinessとしてロードされるというエンティティに伴います。JavassistLaziInitializerfind()EntityManager

get メソッドまたは set メソッドを実行すると、プロキシが使用されて必要@Validな値が返されますが、検証アノテーションを使用すると、実際の値は NULL (コレクションではなく列の値) になるため、次のような検証エラーが発生し@NotNullます。

JavassistLazyInitializer プロキシ値で満たされた列を取得する方法、またはプロキシ自体を取得する方法を誰かが知っていることを期待していました。

私が懸念しているように、この動作は休止状態のバグではなく、バグとして何度か報告されていることに注意してください。ただし、開発者は、特定の状況で発生した休止状態の通常の動作であるとアドバイスしています。

4

1 に答える 1

11

(あなたが言うように) 特定の種類のコードには、「deproxy()」と他のいくつかのヘルパー関数を使用します。

これにより、Spring の「自動拡張」パスバインディングが機能します。Hibernate を介してサブクラス化された可能性のあるエンティティをロードするときに実際の型をチェックするために必要であり、プロキシによって問題が発生するその他のさまざまな面白いコーナーケースに必要です。

public class HbUtils {

    public static <T>  T deproxy (T obj) {
        if (obj == null)
            return obj;
        if (obj instanceof HibernateProxy) {
            // Unwrap Proxy;
            //      -- loading, if necessary.
            HibernateProxy proxy = (HibernateProxy) obj;
            LazyInitializer li = proxy.getHibernateLazyInitializer();
            return (T)  li.getImplementation();
        } 
        return obj;
    }


    public static boolean isProxy (Object obj) {
        if (obj instanceof HibernateProxy)
            return true;
        return false;
    }

    // ----------------------------------------------------------------------------------


    public static boolean isEqual (Object o1, Object o2) {
        if (o1 == o2)
            return true;
        if (o1 == null || o2 == null) 
            return false;
        Object d1 = deproxy(o1);
        Object d2 = deproxy(o2);
        if (d1 == d2 || d1.equals(d2))
            return true;
        return false;
    }

    public static boolean notEqual (Object o1, Object o2) {
        return ! isEqual( o1, o2);
    }

    // ----------------------------------------------------------------------------------

    public static boolean isSame (Object o1, Object o2) {
        if (o1 == o2)
            return true;
        if (o1 == null || o2 == null) 
            return false;
        Object d1 = deproxy(o1);
        Object d2 = deproxy(o2);
        if (d1 == d2)
            return true;
        return false;
    }

    public static boolean notSame (Object o1, Object o2) {
        return ! isSame( o1, o2);
    }



    // ----------------------------------------------------------------------------------

    public static Class getClassWithoutInitializingProxy (Object obj) {
        if (obj instanceof HibernateProxy) {
            HibernateProxy proxy = (HibernateProxy) obj;
            LazyInitializer li = proxy.getHibernateLazyInitializer();
            return li.getPersistentClass();
        } 
        // Not a Proxy.
        return obj.getClass();
    }

}

私はすべての主要な Hibernate プロジェクトでこのようなクラスを使用しています。PS: これは私の唯一の Hibernate ヘルパーではありません。一般的に ID を取得し、エンティティが New/Existent であるかどうかを確認するためのものがあります。

お役に立てれば!

于 2013-05-05T10:58:26.727 に答える