在库内创建SessionFactory时,无法识别NodeEntity



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

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

我的示例应用程序由两个模块组成:模块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);
...
}

模块b包括模块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是否由于new4j 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());
}
}

因此,我认为问题与编译后的类在";正常的";将应用程序部署到应用程序服务器时的类路径?

我感谢您的意见。

非常感谢

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

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结构无关。

最新更新