プロキシでHibernateを使用していますが、などのクラスに属するオブジェクトを取得しますtest.DBUser$$EnhancerByCGLIB$$40e99a2d
。
test.DBUser
プロキシされたクラスから基本クラス(この場合)を取得するためのHibernateメソッドはありますか?については知っていますが、入力としてを受け取るメソッドを探している間は、Hibernate.getClass()
が必要です。Object
Class
Flavioによって投稿されたアプローチの単純さは本当に気に入っていますが、サポートされていると文書化されていない限り、本番コードで使用することはできません。また、LazyInitializerで.getImplementation()を呼び出すと、プロキシがまだ初期化されていない場合は強制的に初期化され、パフォーマンスに悪影響を及ぼします。私はこれらの懸念の両方に対処するこのアプローチを思いついた:
public static Class<?> getClassForHibernateObject(Object object) {
if (object instanceof HibernateProxy) {
LazyInitializer lazyInitializer =
((HibernateProxy) object).getHibernateLazyInitializer();
return lazyInitializer.getPersistentClass();
} else {
return object.getClass();
}
}
思ったより簡単だとわかりました。プロキシされたクラスを呼び出しgetSuperclass()
て、プロキシされていない元のクラスを取得するだけです。これがどれほど一般的かはわかりませんが、機能しているようです。
そのような方法はありません。ラップされたオブジェクトを取得し、プロキシ内からクラス情報を取得するには、ヘルパークラスを自分で作成する必要があります。特定のシナリオでオブジェクトのみが必要な場合は、遅延読み込みをすべて削除してみてください。Hibernateは、プレーンオブジェクトを提供する必要があります。
オブジェクトを必要としないようにすることを検討してください。たとえば、実行時に必要な情報を含むフィールドを追加することで、アプリケーションを不要になるように再設計できます。
のようなクラスtest.DBUser$$EnhancerByCGLIB$$40e99a2d
は動的プロキシです。「実際のクラスの背後にある」という概念は、ほとんどの場合あまり意味がありません。プロキシが作成されるたびに、Hibernateが定義するように、プロキシは任意のクラスのインスタンスになることができます。
あなたが本当に求めているのは静的Map
です{ Class<Proxy>, Class<RealObject>}
。私はそのようなことがあるとは思いませんし、これが必要だとは思いません。のソースを見てくださいHibernate.getClass()
:
339 public static Class getClass(Object proxy) {
340 if ( proxy instanceof HibernateProxy ) {
341 return ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer()
342 .getImplementation()
343 .getClass();
344 }
345 else {
346 return proxy.getClass();
347 }
348 }
静的マップルックアップを実行して実際のクラスを取得する方がはるかに安価ですが、Hibernateはレイジーイニシャライザーに到達して実装クラスを取得します。