lucene java.lang.NoSuchFieldException:带Hibernate升级工厂

egdjgwm8  于 2022-11-07  发布在  Lucene
关注(0)|答案(1)|浏览(100)

我已经将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("factory");收到java.lang.NoSuchFieldException: factory错误
这是什么原因?Hibernate-search-ormLucenehibernate 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;
    }
g0czyy6m

g0czyy6m1#

为什么会这样呢
假设失败的代码是您的代码,那么它本质上是不安全的:

  • 它依赖于一个 * 内部 * 的非API类:AbstractSessionImpl。这些类并不是要供用户访问的。
  • 它使用反射来访问它的一个 private 字段:factory。这些字段并不是要让使用者存取。

简而言之,失败的代码很可能只是一个黑客,而这个黑客在Hibernate ORM/Search的最新版本中不再起作用。
你没有提供完整的堆栈跟踪,所以我不知道代码在哪里。如果代码是你的,你应该找到一个新的黑客。我不能帮助不知道代码应该做什么。如果代码是在Hibernate ORM或搜索,请给予完整的堆栈跟踪。
对于Hibernate 5.4.11,Hibernate搜索表单和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中崩溃。

相关问题