#java #spring-boot #neo4j #mybatis
#java #весенняя загрузка #neo4j #mybatis
Вопрос:
Как следует из названия, я столкнулся с проблемой StackOverflow при подключении к Neo4j в Springboot с помощью Mybatis. CQL хорошо работает на рабочем столе Neo4j, но api возвращает результат 500 с тем же CQL в mapper.
Сообщение об ошибке выглядит следующим образом:
2020-12-31 20:22:24.560 ERROR 31232 --- [nio-9090-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause
java.lang.StackOverflowError: null
at java.io.WinNTFileSystem.normalizePrefix(WinNTFileSystem.java:186) ~[na:1.8.0_261]
at java.io.WinNTFileSystem.normalize(WinNTFileSystem.java:111) ~[na:1.8.0_261]
at java.io.WinNTFileSystem.normalize(WinNTFileSystem.java:93) ~[na:1.8.0_261]
at java.io.File.<init>(File.java:279) ~[na:1.8.0_261]
at java.io.FilePermission$1.run(FilePermission.java:224) ~[na:1.8.0_261]
at java.io.FilePermission$1.run(FilePermission.java:212) ~[na:1.8.0_261]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_261]
at java.io.FilePermission.init(FilePermission.java:212) ~[na:1.8.0_261]
at java.io.FilePermission.<init>(FilePermission.java:299) ~[na:1.8.0_261]
at sun.net.www.protocol.file.FileURLConnection.getPermission(FileURLConnection.java:228) ~[na:1.8.0_261]
at sun.net.www.protocol.jar.JarFileFactory.getPermission(JarFileFactory.java:166) ~[na:1.8.0_261]
at sun.net.www.protocol.jar.JarFileFactory.getCachedJarFile(JarFileFactory.java:136) ~[na:1.8.0_261]
at sun.net.www.protocol.jar.JarFileFactory.get(JarFileFactory.java:91) ~[na:1.8.0_261]
at sun.net.www.protocol.jar.JarURLConnection.connect(JarURLConnection.java:122) ~[na:1.8.0_261]
at sun.net.www.protocol.jar.JarURLConnection.getInputStream(JarURLConnection.java:152) ~[na:1.8.0_261]
at java.net.URLClassLoader.getResourceAsStream(URLClassLoader.java:239) ~[na:1.8.0_261]
at java.lang.Class.getResourceAsStream(Class.java:2223) ~[na:1.8.0_261]
at org.neo4j.jdbc.DatabaseMetaData.<init>(DatabaseMetaData.java:100) ~[neo4j-jdbc-driver-3.1.0.jar:na]
at org.neo4j.jdbc.http.HttpDatabaseMetaData.<init>(HttpDatabaseMetaData.java:34) ~[neo4j-jdbc-driver-3.1.0.jar:na]
at org.neo4j.jdbc.http.HttpDatabaseMetaData.<init>(HttpDatabaseMetaData.java:43) ~[neo4j-jdbc-driver-3.1.0.jar:na]
at org.neo4j.jdbc.http.HttpConnection.getMetaData(HttpConnection.java:105) ~[neo4j-jdbc-driver-3.1.0.jar:na]
at org.neo4j.jdbc.http.HttpConnection.getMetaData(HttpConnection.java:40) ~[neo4j-jdbc-driver-3.1.0.jar:na]
at com.zaxxer.hikari.pool.ProxyConnection.getMetaData(ProxyConnection.java:380) ~[HikariCP-3.4.5.jar:na]
at com.zaxxer.hikari.pool.HikariProxyConnection.getMetaData(HikariProxyConnection.java) ~[HikariCP-3.4.5.jar:na]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getNextResultSet(DefaultResultSetHandler.java:256) ~[mybatis-3.5.2.jar:3.5.2]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getNextResultSet(DefaultResultSetHandler.java:261) ~[mybatis-3.5.2.jar:3.5.2]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getNextResultSet(DefaultResultSetHandler.java:261) ~[mybatis-3.5.2.jar:3.5.2]
at org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getNextResultSet(DefaultResultSetHandler.java:261) ~[mybatis-3.5.2.jar:3.5.2]
(Последняя строка повторялась сотни раз)
Вот мои конфигурации и код:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.neo4j.dw</groupId>
<artifactId>dw</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>amazonMovies</name>
<description>Amazon Movies Data Warehouse</description>
<!-- <properties>-->
<!-- <java.version>1.8</java.version>-->
<!-- </properties>-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Neo4j-->
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-jdbc-driver</artifactId>
<version>3.1.0</version>
</dependency>
<!-- mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- solve: java.lang.NumberFormatException: For input string: "" -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-bean-validators</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- mp -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
<exclusions>
<exclusion>
<artifactId>mybatis</artifactId>
<groupId>org.mybatis</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.9.0</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20190722</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
<!--分页插件 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.4.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>com.neo4j.dw.DwApplication</mainClass>
<excludes>
<exclude>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
</project>
mybatis_config.xml
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="org.neo4j.jdbc.http.HttpDriver"/>
<property name="url" value="jdbc:neo4j:http://localhost:7474"/>
<property name="username" value="neo4j"/>
<property name="password" value="ETL2020"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="./mapper/*.xml"/>
</mappers>
</configuration>
application.yml
spring:
datasource:
driver-class-name: org.neo4j.jdbc.http.HttpDriver
url: jdbc:neo4j:http://localhost:7474
username: neo4j
password: ETL2020
mybatis-plus:
mapper-locations: classpath*:/mapper/**Mapper.xml
type-aliases-package: com.neo4j.dw.Model
server:
port: 9090
TestController
package com.neo4j.dw.Controller;
import com.neo4j.dw.Model.User;
import com.neo4j.dw.Service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private TestService testService;
@GetMapping("/hello")
public String hello(){
return "hello";
}
@GetMapping("/user")
public ArrayList<User> getUsers() {
return testService.selectUsers();
}
}
TestServiceImpl
package com.neo4j.dw.Service.Impl;
import com.neo4j.dw.Mapper.TestMapper;
import com.neo4j.dw.Model.User;
import com.neo4j.dw.Service.TestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
@Service
public class TestServiceImpl implements TestService {
@Autowired
private TestMapper testMapper;
@Override
public ArrayList<User> selectUsers(){
return testMapper.selectUsers();
}
}
TestMapper
package com.neo4j.dw.Mapper;
import com.neo4j.dw.Model.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.ArrayList;
@Mapper
public interface TestMapper {
ArrayList<User> selectUsers();
}
Пользователь
package com.neo4j.dw.Model;
import lombok.*;
import com.baomidou.mybatisplus.annotation.TableField;
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Getter
@Setter
public class User {
@TableField("userId")
public String userId;
@TableField("profileName")
public String profileName;
}
TestMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.neo4j.dw.Mapper.TestMapper">
<select id="selectUsers" resultType="int">
MATCH (n1)-[r]->(n2) RETURN count(*)
</select>
</mapper>
Я новичок в Neo4j и Mybatis.
Кто-нибудь может помочь мне выяснить, как исправить эту ошибку?
Спасибо миллион!
Комментарии:
1. Ошибка SO появляется, когда программа пытается загрузить файл jar из classpath. Путь к файлу, в котором присутствует jar, похоже, вызывает проблему. Вы можете попробовать подключить отладчик и посмотреть, какой путь вызывает эту проблему.
2. Спасибо за ваш совет. Я попытался выполнить отладку и обнаружил, что URL-адрес был неправильно выбран, когда Springboot установил соединение с neo4j. Хост, порт и авторизация являются пустыми значениями. Что-то не так с моей конфигурацией? @Shailendra
Ответ №1:
Насколько я знаю, интеграция MyBatis в:
- ни данные Spring Neo4j 5 (добавлены через
spring-boot-starter-data-neo4j
в вашем POM, включены до Spring Boot 2.3) - ни Neo4j OGM (на котором построена библиотека Spring Data Neo4j 5).
Если вы хотите начать, вам, вероятно, следует начать с Spring Data Neo4j 6 (он же SDN 6), то есть последней версии Spring Data Neo4j на момент написания. Если вы обновите Spring Boot до последней версии (2.4 на момент написания статьи), вы автоматически получите ее.
Вероятно, вам следует начать со справочной документации SDN 6. Вы также можете найти пример здесь.
Как вы узнаете, вы можете избавиться от MyBatis, SDN 6 (и 5 через Neo4j OGM) уже заботится о сопоставлении.
Комментарии:
1. Большое вам спасибо! Я многому научился из вашего предложения!