我已经将休眠模式从5.1.17
升级到5.4.11
,并且与此同时,我还升级了休眠搜索和lucene。下面是详细信息
Hibernate: 5.1.17 to 5.4.11
Hibernate-search-orm: 5.5.2 to 5.11.5
Lucene: 5.3.1 to 5.5.5
我在java.lang.NoSuchFieldException: factory
遇到AbstractSessionImpl.class.getDeclaredField("factory");
错误
这是什么原因?
对于Hibernate-search-orm
,Lucene
和hibernate 5.4.11
的建议/兼容性是什么?
编辑:这是引起问题的地方,并且此代码长期存在。 运行测试用例时遇到了这个问题,它指向我们代码中的以下方法。
private Set<String> getAllQueryNames() {
Set<String> queryNames = Sets.newHashSet();
try {
Field factoryField = AbstractSessionImpl.class.getDeclaredField("factory");
factoryField.setAccessible(true);
SessionFactoryImpl factory = (SessionFactoryImpl) factoryField.get(getSessionFactory().getCurrentSession());
Field namedQueriesField = SessionFactoryImpl.class.getDeclaredField("namedQueryRepository");
namedQueriesField.setAccessible(true);
NamedQueryRepository namedQueryRepository = (NamedQueryRepository) namedQueriesField.get(factory);
Field namedQueryDefinitionMapField = NamedQueryRepository.class.getDeclaredField("namedQueryDefinitionMap");
namedQueryDefinitionMapField.setAccessible(true);
Map namedQueryDefinitionMap = (Map) namedQueryDefinitionMapField.get(namedQueryRepository);
queryNames.addAll(namedQueryDefinitionMap.keySet());
} catch (SecurityException e) {
throw new RuntimeException(e);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalArgumentException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
return queryNames;
}
答案 0 :(得分:1)
这是什么原因
假设失败的代码是您自己的,那本质上是不安全的:
AbstractSessionImpl
。这些类并不意味着用户可以访问。factory
。这些字段并不意味着用户可以访问。简而言之,失败的代码很可能只是一种破解,并且这种破解在Hibernate ORM / Search的最新版本中不再有效。
您没有提供完整的堆栈跟踪,所以我不知道代码在哪里。 如果代码是您自己的,则应该找到一个新的技巧。我不知道代码应该做什么。 如果代码在Hibernate ORM或Search中,请提供完整的堆栈跟踪。
对于Hibernate 5.4.11,Hibernate-search-orm和Lucene的建议/兼容性是什么?
您使用的版本很好。如果您想确定,请签出the compatibility matrix。如上所述,问题出在黑客攻击上。
编辑:所以,这是一个黑客。您应该尽可能多地使用SPI。代替这个:
Field factoryField = AbstractSessionImpl.class.getDeclaredField("factory");
factoryField.setAccessible(true);
SessionFactoryImpl factory = (SessionFactoryImpl) factoryField.get(getSessionFactory().getCurrentSession());
Field namedQueriesField = SessionFactoryImpl.class.getDeclaredField("namedQueryRepository");
namedQueriesField.setAccessible(true);
NamedQueryRepository namedQueryRepository = (NamedQueryRepository) namedQueriesField.get(factory);
Field namedQueryDefinitionMapField = NamedQueryRepository.class.getDeclaredField("namedQueryDefinitionMap");
namedQueryDefinitionMapField.setAccessible(true);
Map namedQueryDefinitionMap = (Map) namedQueryDefinitionMapField.get(namedQueryRepository);
执行此操作:
NamedQueryRepository namedQueryRepository = getSessionFactory().unwrap(SessionFactoryImplementor.class)
.getNamedQueryRepository()
Field namedQueryDefinitionMapField = NamedQueryRepository.class.getDeclaredField("namedQueryDefinitionMap");
namedQueryDefinitionMapField.setAccessible(true);
Map namedQueryDefinitionMap = (Map) namedQueryDefinitionMapField.get(namedQueryRepository);
第二部分仍然是黑客,仍然很脆弱,并且可能会在下一版本的Hibernate ORM中中断。但是至少现在应该可以。