2013-05-05 43 views
3

我使用Spring来开发我的应用程序,使用Hibernate和JPA作为MySQL数据库中的持久性API。当我从数据库中获取大部分对象时,它们的属性都使用数据库的值进行初始化,并且集合是Lazy加载的。问题出现在名为Business的实体中,该实体使用方法find()EntityManager加载为JavassistLaziInitializerHibernate JavassistLazyInitializer:验证问题

如果我执行get或set方法,他们使用代理并给我所需的值,但是当我使用@Valid和验证注释时,由于实际值为NULL(列值而不是集合),所以我有验证错误,如@NotNull

我希望是否有人知道一个方法来获得充满JavassistLazyInitializer代理值的列或一种方法来获取代理本身。

请注意,这一行为,因为我关心的不是hibernate上的一个bug,因为它已被多次报告为bug,但是开发者建议是在某些条件下发生的正常hibernate行为。

回答

10

对于(如你所说),我使用'deproxy()'和一些其他的辅助函数,某些类型的代码。

这使得Spring'autogrow'路径绑定工作,在通过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并检查实体是新/存在的。

希望这会有所帮助!

+0

我已经测试过它并且完美地工作。非常感谢你,这让我失去了很多时间! – droidpl 2013-05-05 11:05:54

+0

不客气! – 2013-05-05 11:20:50

+0

这个util对我很有帮助。非常感谢你 – 2016-01-15 02:55:58