2013-05-05 3 views
3

Я использую Spring для разработки моего приложения с использованием Hibernate и JPA в качестве API Persistence в базе данных MySQL. Когда я извлекаю большинство своих объектов из базы данных, они имеют свои атрибуты, инициализированные значениями базы данных, а коллекции загружаются с помощью Lazy. Проблема связана с объектом под названием Business, который загружается как JavassistLaziInitializer с использованием метода find() от EntityManager.Hibernate JavassistLazyInitializer: проблемы с проверкой

Если я выполняю метод get или set, они используют прокси-сервер и дают мне значения, которые мне нужны, но когда я использую @Valid и аннотации валидации, так как реальные значения имеют значение NULL (значения столбца, а не коллекции), у меня есть ошибки проверки, такие как @NotNull.

Я надеялся, если кто-нибудь знает способ получения столбцов, заполненных значениями прокси-сервера JavassistLazyInitializer, или метод для получения самого прокси-сервера.

Обратите внимание, что такое поведение, как я уже говорил, не является ошибкой в ​​спящем режиме, поскольку оно было сообщено несколько раз как ошибка, но разработчики советуют, что это нормальное поведение спящего режима, которое происходит в определенных условиях.

ответ

10

Я использую 'deproxy()' и пару других вспомогательных функций, для (как вы говорите) определенных типов кода.

Это делает обязательным связывание пути «autogrow», которое необходимо для проверки фактических типов при загрузке, возможно, подклассифицированных объектов через спящий режим, а также для различных других забавных угловых случаев, когда проксирование приводит к разрыву вещей.

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 - у меня есть один для получения идентификаторов и проверки того, являются ли сущности новыми/существующими.

Надеюсь, это поможет!

+0

Я проверил его и отлично работает. Большое вам спасибо, это заставило меня потерять много времени! – droidpl

+0

Добро пожаловать! –

+0

Этот прием очень полезен для меня. Большое спасибо –

Смежные вопросы