hibernate 5.0+equinox 4.5.0和自定义UserType



我能够让Hibernate 5.0 Osgi Bundles在Unmanaged JPA模式下与Equinox 4.5.0一起工作。但是有一个问题,当我在我的一个实体中使用自定义UserType(例如实现EnhancedUserType的TestTypeMapType)时,我会得到以下异常:

org.hibernate.MappingException: Could not determine type for: com.xxx.yyy.TestTypeMapType, at table: TestTable, for columns: [org.hibernate.mapping.Column(testType)]
at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:390)

当我从Hibernate源代码中检查SimpleValue.java时,我发现它正在使用org.Hibernate.internal.util.Reflecthelper创建类型信息,代码为

ReflectHelper.classForName(typeName);

ReflectHelper正在使用以下行创建类型信息

try {
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    if (classLoader != null) {
        return classLoader.loadClass(typeName);
    }
}
catch(Throwable ignore){}
return Class.forName(typeName);

classLoader.loadClass和Class.forName都抛出以下异常

java.lang.ClassNotFoundException: com.xxx.yyy.TestTypeMapType cannot be found by org.hibernate.core_5.0.2.Final

但是,如果我直接从创建EntityManagerFactory的捆绑包中执行ReflectHelper.classForName内容,我可以成功地创建自定义UserType的类型信息。特别是对于下面的示例,线路A和线路B工作,但线路C抛出异常。

try {
    Class<?> typeClass = null;
    // A
    typeClass = Thread.currentThread().getContextClassLoader().loadClass("com.xxx.yyy.TestTypeMapType");
    // B
    typeClass = Class.forName("com.xxx.yyy.TestTypeMapType");
    // C
    typeClass = ReflectHelper.classForName("com.xxx.yyy.TestTypeMapType");
}
catch(Exception e){}

我能做些什么,让hibernate在osgi环境中发现我的自定义UserType?

PS:我对其他Entity类、方言、jdbc驱动程序等没有问题,而且ReflectHelper.classForName也不推荐使用,建议使用ClassLoaderService或ClassLoaderAccess。它会是冬眠虫吗?

谢谢。。。

您需要使用此处描述的TypeContributor扩展点。

https://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#_extension_points

示例如何在hibernate环境中完成:

https://github.com/hibernate/hibernate-orm/blob/master/hibernate-envers/src/main/resources/OSGI-INF/blueprint/blueprint.xml

注意:您应该在不直接或间接使用实体管理器实例的捆绑包中注册类型贡献者。否则,您的类型贡献者将不会用于创建实体管理器。我花了很多时间调试这个。最好只为用户类型提供一个单独的捆绑包。

最新更新