java.lang.NoSuchFieldException:具有hibernate升级的工厂

java.lang.NoSuchFieldException:具有hibernate升级的工厂,hibernate,lucene,hibernate-search,Hibernate,Lucene,Hibernate Search,我已经将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 我在AbstractSessionImpl.class.getDeclaredField(“工厂”)中得到java.lang.NoSuchFieldException:factory错误 原因是什

我已经将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
我在
AbstractSessionImpl.class.getDeclaredField(“工厂”)中得到
java.lang.NoSuchFieldException:factory
错误

原因是什么? 对于
Hibernate 5.4.11
Hibernate搜索orm
Lucene
的建议/兼容性是什么

编辑:这是它引起问题的地方,此代码长期存在。 我在运行测试用例时遇到了这个问题,它指向代码中的以下方法

 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;
    }
private Set getAllQueryNames(){
Set queryNames=Sets.newHashSet();
试一试{
Field factoryField=AbstractSessionImpl.class.getDeclaredField(“工厂”);
factoryField.setAccessible(true);
SessionFactoryImpl工厂=(SessionFactoryImpl)factoryField.get(getSessionFactory().getCurrentSession());
字段namedQueriesField=SessionFactoryImpl.class.getDeclaredField(“namedQueryRepository”);
namedQueriesField.setAccessible(true);
NamedQueryRepository NamedQueryRepository=(NamedQueryRepository)namedQueriesField.get(工厂);
字段namedQueryDefinitionMapField=NamedQueryRepository.class.getDeclaredField(“namedQueryDefinitionMap”);
namedQueryDefinitionMapField.setAccessible(true);
Map namedQueryDefinitionMap=(Map)namedQueryDefinitionMapField.get(namedQueryRepository);
queryNames.addAll(namedQueryDefinitionMap.keySet());
}捕获(安全异常e){
抛出新的运行时异常(e);
}捕获(无此字段例外){
抛出新的运行时异常(e);
}捕获(IllegalArgumentException e){
抛出新的运行时异常(e);
}捕获(非法访问例外e){
抛出新的运行时异常(e);
}
返回queryNames;
}
原因是什么

假设失败的代码是您的,它本质上是不安全的:

  • 它依赖于一个内部的非API类:
    AbstractSessionImpl
    。这些类并不意味着用户可以访问
  • 它使用反射来访问它的一个私有字段:
    factory
    。这些字段不允许用户访问
简言之,失败的代码很可能只是一种黑客行为,而这种黑客行为在Hibernate ORM/Search的最新版本中不再有效

你没有提供完整的堆栈跟踪,所以我不知道代码在哪里。 如果代码是你的,你应该找到一个新的黑客。如果不知道代码应该做什么,我就无能为力。 如果代码在Hibernate ORM或Search中,请提供完整的堆栈跟踪

Hibernate 5.4.11版的Hibernate搜索orm和Lucene的建议/兼容性是什么

您使用的版本很好。如果你想确定,请退房。问题在于黑客,如上所述

编辑:所以,这是一个黑客。您应该尽可能多地使用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中被破解。但至少现在应该可以用了。

谢谢你的回复。我也遵循相同的矩阵进行兼容性检查。谢谢你的确认。我在问题中补充了细节。请检查我的编辑,如果您还需要什么,请告诉我。我可以看到
AbstractSessionImpl
已被修改,并且引入了一个新类
AbstractSharedSessionContract
。我想要么我应该改变方法实现,要么我应该使用这个新类。非常感谢。我会尽力让你知道的。