2012-11-24 5 views
5

Używam Hibernuj z serwerami proxy, a otrzymuję obiekty należące do klas, takich jak test.DBUser$$EnhancerByCGLIB$$40e99a2d.Jak mogę pobrać klasę pośrednią z klasy proxy?

Czy istnieje metoda hibernacji, aby pobrać klasę podstawową (test.DBUser w tym przypadku) z Proxy klasy? Wiem o Hibernate.getClass(), ale zajmuje Object, a ja szukam metody, która przyjmuje jako dane wejściowe Class.

+1

Po co ci to na początku? Proxy rozszerza twoją klasę podstawową, więc każda metoda wywoływania instancji klasy bazowej może być również wywołana na serwerze proxy i spowoduje powrót do tej samej rzeczy. –

+0

Szukałem tego w kolejnym pytaniu o przekazywaniu obiektów w trybie hibernacji do biblioteki GSON. Biblioteka sprawia, że ​​niektóre wywołania przekazują implementorom proxy 'Class', a dopiero później proxy' Object', i chciałem móc zacząć coś robić z 'Class'. – Flavio

Odpowiedz

3

Dowiedziałem się, że jest łatwiej niż myślałem: wystarczy zadzwonić pod numer getSuperclass(), aby uzyskać niezwiązaną, oryginalną klasę. Nie jestem pewien, jaki to jest ogólny, ale wygląda na to, że działa.

0

Klasy takie jak test.DBUser$$EnhancerByCGLIB$$40e99a2d to dynamic proxies. Pojęcie "prawdziwa klasa za" w większości przypadków nie ma większego sensu. Za każdym razem, gdy tworzony jest serwer proxy, może on być instancją dowolnej klasy zdefiniowanej przez Hibernate.

Co to jest naprawdę z prośbą o statyczne Map z { Class<Proxy>, Class<RealObject>}. Nie wierzę, że coś takiego istnieje, i nie uważam, że jest taka potrzeba. Wystarczy spojrzeć na źródła 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 } 

Byłoby o wiele tańsze zrobić mapie statycznej odnośnika, aby uzyskać rzeczywistą klasę, ale hibernacji idzie aż do leniwego inicjatora, aby uzyskać klasę wykonawczą.

0

Nie ma takiej metody. Będziesz musiał sam napisać klasę pomocnika, aby pobrać zawinięty obiekt, a tym samym informacje o klasie z wnętrza proxy. Jeśli potrzebujesz tylko obiektu w danym scenariuszu, spróbuj usunąć wszystkie leniwy ładunek. Hibernacja powinna dać ci prosty obiekt.

Rozważ próbowanie nie potrzebować obiektu. Może możesz przeprojektować aplikację tak, aby jej nie potrzebować, na przykład dodając pole zawierające żądane informacje w czasie wykonywania.

3

Chociaż bardzo podoba mi się prostota podejścia opublikowanego przez Flavio, nie mogę go użyć w kodzie produkcyjnym, chyba że jest to udokumentowane jako obsługiwane. Ponadto, jeśli wywołasz funkcję .getImplementation() na LazyInitializer, wymusi inicjalizację proxy, jeśli jeszcze nie jest, co ma negatywny wpływ na wydajność. Wymyśliłem to podejście, które dotyczy obu tych kwestii:

public static Class<?> getClassForHibernateObject(Object object) { 
    if (object instanceof HibernateProxy) { 
    LazyInitializer lazyInitializer = 
     ((HibernateProxy) object).getHibernateLazyInitializer(); 
    return lazyInitializer.getPersistentClass(); 
    } else { 
    return object.getClass(); 
    } 
} 
Powiązane problemy