我有用户和景点。每个用户可以收藏多个地点,并且一个用户可以收藏多个地点。
我编写了一个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。我是个初学者,所以对如何更好地组织代码的任何提示都表示赞赏。