【问题标题】:NodeEntity not recognized when SessionFactory is created inside library在库中创建 SessionFactory 时无法识别 NodeEntity
【发布时间】:2021-07-06 09:58:06
【问题描述】:

我不确定我的问题是不存在的功能还是我错误地使用了 neo4j-ogm 框架。由于您只应该在项目 GitHub 存储库中发布错误或功能请求,所以我想先在这里提出我的问题。

请注意,我缩短了我的真实代码,只是为了让您了解我试图实现的目标。

我的示例应用程序包含两个模块: Module a 包含一个用于创建 neo4j-ogm 会话的类。在那里我从属性文件中读取配置并创建会话工厂,将包作为参数传递给扫描:

public Neo4jController(final String ... packagesWithNodes) {
    ConfigurationSource props = new ClasspathConfigurationSource("neo4jogm.properties");
    Configuration configuration = new Configuration.Builder(props).build();

    SessionFactory sessionFactory = new SessionFactory(configuration, packagesWithNodes);
    ...
}

Module b 包含 module a 作为 Maven 依赖项,然后尝试通过 Session 对象持久化 NodeEntitySession创建正确,但传递包中的NodeEntity无法识别。

public MyObject create(final MyObject newObject) {
  Neo4jController neo4jController = new Neo4jController("my.example.package");
  neo4jController.getNeo4jSession().save(newObject);

  ...
}

这总是导致IllegalArgumentException

Class class my.example.package.MyObject is not a valid entity class. Please check the entity mapping.

这就是我在模块 b 中的NodeEntity 的样子

package my.example.package;

import de.bitandgo.workflow.common.model.Neo4jNode;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Property;

@NodeEntity(label = "MyObject")
public class MyObject extends Neo4jNode {

  @Property
  public String name;
}

基类包含其他内容

public abstract class Neo4jNode {

    @Id
    @GeneratedValue
    private Long id;
}

我知道 neo4j-ogm 在内部使用 glassgraph 来扫描类路径。框架中带有前置配置的相应调用如下所示:

private static List<String> useClassgraph(String[] packagesOrClasses) {

    // .enableExternalClasses() is not needed, as the super classes are loaded anywhere when the class is loaded.
    try (ScanResult scanResult = new ClassGraph()
        .ignoreClassVisibility()
        .acceptPackages(packagesOrClasses)
        .acceptClasses(packagesOrClasses)
        .scan()) {
        return scanResult.getAllClasses().getNames();
    }
}

通过调试,我验证了所需的包 my.example.package 已作为参数传递给 GlassGraph 对象。

模块 a 中的 Neo4jController 也能够加载该类。我已经用以下代码对此进行了测试

try {
  Class<?> aClass = Class.forName("my.example.package.MyObject");
  System.out.println(aClass);  // prints "class my.example.package.MyObject"
} catch (ClassNotFoundException e) {}

我的问题是 neo4j-ogm/classgraph 是否可能由于 neo4j-ogm 的方式根本无法找到课程使用 classgraph,或者如果我在使用中做错了什么。

更新 1: 该问题似乎与我在应用程序服务器 (TomEE) 中运行的应用程序有关。当我部署我的应用程序 ClassGraph 时找不到配置的包。 但是通过经典的main 方法执行完全相同的扫描会找到我期望的类。

public static void main(String[] args) {
        try (ScanResult scanResult = new ClassGraph()
                .ignoreClassVisibility()
                .acceptPackages("my.example.package")
                .acceptClasses()
                .scan()) {
            System.out.println(scanResult.getAllClasses().getNames());
        }
    }

所以我认为问题与将应用程序部署到应用程序服务器时在“正常”类路径中不可见的编译类有关?

感谢任何意见。

非常感谢

【问题讨论】:

    标签: classpath neo4j-ogm classgraph


    【解决方案1】:

    问题确实与 neo4j-ogm 用于扫描模型文件的类路径的 glassgraph 库有关。

    glassgraph 支持多种类加载器,但尚未包含 TomEE 之一。这个问题已经从 4.8.107 版本开始修复,所以如果您遇到类似问题,请检查 glassgraph 是否支持您使用的应用服务器的类加载器。

    您可以通过在 pom.xml 中指定您需要的版本来轻松覆盖 neo4j-ogm 的类图依赖项。

    <dependency>
      <groupId>org.neo4j</groupId>
      <artifactId>neo4j-ogm-core</artifactId>
      <version>${neo4j-version}</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>org.neo4j</groupId>
      <artifactId>neo4j-ogm-bolt-driver</artifactId>
      <version>${neo4j-version}</version>
      <scope>runtime</scope>
    </dependency>
    
    <!-- overwriting the internal classloader of neo4j-ogm because it's used version does not support ApacheTomEE -->
    <dependency>
      <groupId>io.github.classgraph</groupId>
      <artifactId>classgraph</artifactId>
      <version>4.8.107</version>
    </dependency>
    

    问题与我的多模块 Maven 结构无关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-04-21
      • 2017-10-23
      • 2013-08-11
      • 1970-01-01
      • 2021-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多