java.lang.Ошибка StackOverflowError происходит при подключении к Neo4j в Springboot Mybatis

#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. Большое вам спасибо! Я многому научился из вашего предложения!