我已经将hibernate从5.1.17升级到5.4.11,同时还升级了hibernate搜索和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;
}发布于 2020-04-20 08:00:14
会有什么原因
假设失败的代码是您的,它本质上是不安全的:
AbstractSessionImpl。这些类不打算供用户访问。factory。这些字段不打算供用户访问。简而言之,失败的代码很可能只是一次黑客攻击,而该黑客在Hibernate ORM/Search的最新版本中已不再起作用。
您没有提供完整的堆栈跟踪,所以我不知道代码在哪里。如果代码是你的,你应该找到一个新的黑客。如果不知道代码应该做什么,我就忍不住了。如果代码在Hibernate ORM或Search中,请给出完整的堆栈跟踪。
Hibernate-search-orm和Lucene对hibernate 5.4.11的建议/兼容是什么?
你使用的版本很好。如果您想确定,请查看相容矩阵。正如上面所解释的,问题就在黑客攻击上。
编辑:那么,这是一个黑客。你应该尽可能多地使用SPIs。而不是这样:
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。但至少现在应该有效。
https://stackoverflow.com/questions/61316099
复制相似问题