Spring 5服务在任何查询上返回空异常

时间:2019-03-10 07:46:42

标签: spring spring-boot spring-mvc h2

我有用户和景点。每个用户可以收藏多个地点,并且一个用户可以收藏多个地点。

我编写了一个rest 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实例。为什么?!

P.S。我是个初学者,所以对如何更好地组织代码的任何提示都表示赞赏。

0 个答案:

没有答案