hibernate 5.0 + equinox 4.5.0和自定义UserType

时间:2015-11-18 16:51:35

标签: hibernate jpa osgi equinox compositeusertype

我能够在非托管JPA模式下使用Hibernate 5.0 Osgi Bundles与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的bundle执行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){}

我可以做什么,以便在osgi环境中通过hibernate发现我的自定义UserType?

PS:我对其他实体类,方言,jdbc驱动程序等没有任何问题,并且不推荐使用ReflectHelper.classForName,建议使用ClassLoaderService或ClassLoaderAccess。它可以是一个hibernate错误吗?

谢谢...

1 个答案:

答案 0 :(得分:0)

您需要按照此处所述使用TypeContributor扩展点。

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

示例如何在休眠时启用:

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

注意::您应在不直接或间接使用实体管理器实例的捆绑软件中注册类型贡献者。否则,您的类型贡献者将不会用于创建实体管理器。我花了很多时间调试它。最好仅针对用户类型使用单独的捆绑软件。