Сервис Spring 5 возвращает нулевое исключение при любом запросе - PullRequest
0 голосов
/ 10 марта 2019

У меня есть пользователи и точки.Каждый пользователь может добавить в избранное несколько точек, а несколько точек могут быть добавлены в список.

Я написал API отдыха, который может отображать пятна в моей базе данных H2.

package spring.backend.springmvcrest.controllers;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import spring.backend.springmvcrest.model.Spot;
import spring.backend.springmvcrest.services.SpotService;
import java.util.List;

@RestController
@RequestMapping(SpotController.BASE_URL)
public class SpotController {

    public static final String BASE_URL = "/api/spots";

    private final SpotService spotService;

    public SpotController(SpotService spotService) {
        this.spotService = spotService;
    }

    @GetMapping
    public List<Spot> getAllSpots(){
        return spotService.findAllSpots();
    }

    @GetMapping("/{id}")
    public Spot getSpotById(@PathVariable Long id){
        return spotService.findSpotById(id);
    }
}

package spring.backend.springmvcrest.services;

import org.springframework.stereotype.Service;
import spring.backend.springmvcrest.model.Spot;
import spring.backend.springmvcrest.repositories.SpotRepository;

import java.util.List;
@Service
public class SpotServiceImpl implements SpotService {

    private final SpotRepository spotRepository;

    public SpotServiceImpl(SpotRepository spotRepository) {
        this.spotRepository = spotRepository;
    }

    @Override
    public Spot findSpotById(Long id) {
        return spotRepository.findById(id).get();
    }

    @Override
    public List<Spot> findAllSpots() {
        return spotRepository.findAll();
    }
}

package spring.backend.springmvcrest.repositories;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import spring.backend.springmvcrest.model.Spot;

@Repository
public interface SpotRepository extends JpaRepository<Spot, Long> {
}

package spring.backend.springmvcrest.model;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Data
@Entity
@EqualsAndHashCode(exclude = "users")
public class Spot {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private float longitude;
    private float latitude;
    private float wind;
    @ManyToOne
    @JsonManagedReference
    private Country country;
    private String month;

    @ManyToMany
    @JoinTable(name = "favorites",
        joinColumns = @JoinColumn(name = "spot_id"),
        inverseJoinColumns = @JoinColumn(name = "user_id"))
    @JsonBackReference
    private Set<User> users = new HashSet<>();
}

Это работает нормально и возвращает все места, которые есть в моей базе данных H2 (доказывая, что места есть)

Теперь я хочу создать любимую запись для пользователя.Поэтому мне нужен spot_id user_id и сервис, который может сделать это + контроллер.Итак, я написал это:

package spring.backend.springmvcrest.controllers;


import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import spring.backend.springmvcrest.model.User;
import spring.backend.springmvcrest.services.FavoriteService;

import java.util.Map;

@RestController
@RequestMapping(FavoriteController.BASE_URL)
public class FavoriteController {

    public static final String BASE_URL = "/api/favorites/spots";

    private final FavoriteService favoriteService;

    public FavoriteController(FavoriteService favoriteService) {
        this.favoriteService = favoriteService;
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public User create(@RequestBody Map<String, Object> body){
        Long user_id = Long.valueOf(body.get("user_id").toString()).longValue();
        Long spot_id = Long.valueOf(body.get("spot_id").toString()).longValue();
        return favoriteService.create(user_id, spot_id);
    }
}

package spring.backend.springmvcrest.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import spring.backend.springmvcrest.model.Spot;
import spring.backend.springmvcrest.model.User;
import spring.backend.springmvcrest.repositories.SpotRepository;
import spring.backend.springmvcrest.repositories.UserRepository;

@Service
public class FavoriteServiceImpl implements FavoriteService {

    private final UserRepository userRepository;
    private final SpotRepository spotRepository;

    public FavoriteServiceImpl(UserRepository userRepository, SpotRepository spotRepository) {
        this.userRepository = userRepository;
        this.spotRepository = spotRepository;
        System.out.println("dwadwadwadwa");
        System.out.println(this.userRepository);
    }


    @Override
    public User create(Long user_id, Long spot_id) {
        System.out.println("balalalalala");
        System.out.println(user_id);
        System.out.println(spot_id);
        System.out.println(this.userRepository);
        System.out.println(spotRepository.findAll().toString());
        System.out.println(userRepository.findAll().toString());
        System.out.println("balalalalala");
        User user = userRepository.findById(user_id).get();

        System.out.println(user);
        Spot spot = spotRepository.findById(spot_id).get();

        //System.out.println(spot);

        System.out.println(user.getSpots());
        user.getSpots().add(spot);
        //spot.getUsers().add(user);
        userRepository.save(user);
        //spotRepository.save(spot);

        return user;
    }

    @Override
    public void delete(Long user_id, Long spot_id) {

    }
}

Теперь в этом сервисе, даже если все идентично предыдущему сервису, я получаю нулевую ошибку, когда я выполняю spotRepository.findAll () (или любую другую операцию SQL)

Полный код можно найти здесь: https://github.com/lucianacimbir/spring-mvc-rest/tree/add-spots-delete-post

Ошибка:

2019-03-09 23:39:06.026 ERROR 5690 --- [nio-8080-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 org.h2.command.Parser.readTerm(Parser.java:3093) ~[h2-1.4.197.jar:1.4.197]
    at org.h2.command.Parser.readFactor(Parser.java:2587) ~[h2-1.4.197.jar:1.4.197]
    at org.h2.command.Parser.readSum(Parser.java:2574) ~[h2-1.4.197.jar:1.4.197]
    at org.h2.command.Parser.readConcat(Parser.java:2544) ~[h2-1.4.197.jar:1.4.197]
    at org.h2.command.Parser.readCondition(Parser.java:2370) ~[h2-1.4.197.jar:1.4.197]

Любая подсказка, почему это может вызвать ошибку?Это приложение Spring 5.

РЕДАКТИРОВАНИЕ 1: Кажется, что spotRepository.findById возвращает spot_instance.toString () вместо экземпляра Spot.ПОЧЕМУ?!

PS Я новичок, поэтому любые советы о том, как лучше организовать код, приветствуются.

...