项目发布时Owning ClassInfo is null for property: private问题原因排查与解决 neo4j
问题现象
该问题的现象是,通过idea之类IDE开发平台运行和打包时一切正常,但打包jar后启动时提示警告:
main] o.s.d.n.mapping.Neo4jPersistentProperty : Owning ClassInfo is null for property: private…
工程接口被调用时出错,无法识别实体。
原因分析
根据警告分析,jar在启动时没有成功扫描到所有的Entity实体导致后面应用时出现问题。
由于maven工程在打包jar时会添加/BOOT-INF的目录结构导致扫描时结构与研发环境不同所致。
问题解决思路
代码排查
项目中使用的是neo4j-ogm-http-driver
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm-http-driver</artifactId>
</dependency>
1 package com.xxxxx.neo.config; 2 3 import org.apache.logging.log4j.util.Strings; 4 import org.neo4j.ogm.config.ClasspathConfigurationSource; 5 import org.neo4j.ogm.config.ConfigurationSource; 6 import org.neo4j.ogm.session.SessionFactory; 7 import org.springframework.beans.factory.annotation.Value; 8 import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 9 import org.springframework.boot.autoconfigure.domain.EntityScan; 10 import org.springframework.context.annotation.Bean; 11 import org.springframework.context.annotation.Configuration; 12 import org.springframework.data.neo4j.annotation.EnableNeo4jAuditing; 13 import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories; 14 import org.springframework.data.neo4j.transaction.Neo4jTransactionManager; 15 import org.springframework.transaction.annotation.EnableTransactionManagement; 16 @Configuration 17 @EnableNeo4jAuditing 18 @EnableNeo4jRepositories(basePackages = "com.xxxx.neo.repository") 19 @EnableTransactionManagement // 激活SDN隐式事务 20 public class Neo4jConfig { 21 @Value("${spring.data.neo4j.uri}") 22 private String uri; 23 24 @Value("${spring.data.neo4j.username}") 25 private String username; 26 27 @Value("${spring.data.neo4j.password}") 28 private String password; 29 30 @Value("${spring.data.neo4j.connection.pool.size}") 31 private Integer connectionPoolSize; 32 33 34 @Bean 35 public SessionFactory sessionFactory() { 36 SessionFactory sessionFactory = new SessionFactory(configuration(), "com.xxxxx.neo.entity"); 37 return sessionFactory; 38 } 39 40 @Bean 41 public org.neo4j.ogm.config.Configuration configuration() { 42 return new org.neo4j.ogm.config.Configuration.Builder() 43 .uri(uri) 44 .credentials(username, password) 45 .connectionPoolSize(connectionPoolSize) 46 .autoIndex("update") 47 .build(); 48 } 49 50 @Bean 51 public Neo4jTransactionManager transactionManager() { 52 return new Neo4jTransactionManager(sessionFactory()); 53 } 54 55 }
application.yml
1 server: 2 port: 8877 3 servlet: 4 context-path: / 5 spring: 6 data: 7 neo4j: 8 uri: bolt://127.0.0.1:7687 9 username: neo4j 10 password: 1 11 auto-index: update 12 open-in-view: false 13 repositories: 14 enabled: true 15 embedded: 16 enabled: true 17 connection: 18 pool: 19 size: 100
由此看来是创建SessionFactory时指定packages没有被扫描到。最后跟踪到org.neo4j.ogm.metadata.DomainInfo:
1 public static DomainInfo create(String... packages) { 2 ScanResult scanResult = (new FastClasspathScanner(packages)).strictWhitelist().scan(); 3 List<String> allClasses = scanResult.getNamesOfAllClasses(); 4 DomainInfo domainInfo = new DomainInfo(); 5 allClasses.forEach((className) -> { 6 prepareClass(domainInfo, className); 7 }); 8 domainInfo.finish(); 9 return domainInfo; 10 }
FastClasspathScanner的问题;
解决办法:
节点和边的路径加入到配置文件
1 @Configuration 2 @EnableNeo4jRepositories(basePackages = "com.study.Repository") 3 @EnableTransactionManagement // 激活SDN隐式事务 4 public class Neo4jConfig { 5 6 @Value("${spring.data.neo4j.uri}") 7 private String databaseUrl; 8 9 @Value("${spring.data.neo4j.username}") 10 private String userName; 11 12 @Value("${spring.data.neo4j.password}") 13 private String password; 14 15 @Bean 16 public SessionFactory sessionFactory() { 17 org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration.Builder() 18 .uri(databaseUrl) 19 .credentials(userName, password) 20 .build(); 21 return new SessionFactory(configuration, "com.study.node", "com.study.relation"); 22 } 23 24 @Bean 25 public Neo4jTransactionManager transactionManager() { 26 return new Neo4jTransactionManager(sessionFactory()); 27 }