문제 설명
최대 절전 모드 5.0 + 춘분 4.5.0 및 사용자 정의 UserType (hibernate 5.0 + equinox 4.5.0 and custom UserType)
비관리 JPA 모드에서 Hibernate 5.0 Osgi 번들이 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의 유형 정보를 성공적으로 생성할 수 있습니다. 특히 아래 예제의 경우 line‑A와 line‑B는 작동하지만 line‑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 환경의 최대 절전 모드에서 내 사용자 지정 UserType을 검색할 수 있도록 어떻게 해야 하나요?
p>PS: 다른 Entity 클래스, 언어, jdbc 드라이버 등에 문제가 없습니다. 또한 ReflectHelper.classForName은 더 이상 사용되지 않으며 ClassLoaderService 또는 ClassLoaderAccess를 사용하는 것이 좋습니다. 최대 절전 모드 버그인가요?
감사합니다...
다른 Entity 클래스, 방언, jdbc 드라이버 등에 문제가 없습니다. 또한 ReflectHelper.classForName은 더 이상 사용되지 않으며 ClassLoaderService 또는 ClassLoaderAccess를 사용하는 것이 좋습니다. 최대 절전 모드 버그인가요?감사합니다...
다른 Entity 클래스, 방언, jdbc 드라이버 등에 문제가 없습니다. 또한 ReflectHelper.classForName은 더 이상 사용되지 않으며 ClassLoaderService 또는 ClassLoaderAccess를 사용하는 것이 좋습니다. 최대 절전 모드 버그인가요?감사합니다...
참조 솔루션
방법 1:
You need to use TypeContributor extension point as described here.
Example how it is done is at hibernate envers:
NOTE: You should register type contributor in the bundle that does not use entity manager instance directly or indirectly. Otherwise your type contributor will not be used for entity manager creation. I spent a lot of time debugging this. It is better to have a separate bundle just for user types.
(by exoz、user1936595)