Java Spring引导REST API-一对多关系的未解析前向引用

Java Spring引导REST API-一对多关系的未解析前向引用,java,rest,spring-boot,Java,Rest,Spring Boot,我目前正在从事SpringBoot中的RESTAPI项目。我创建了两个实体——玩家和团队,它们通过一对多的关系联系在一起 基本上,问题是当我尝试创建新的玩家,然后创建新的团队并将玩家分配给它时。我做了以下工作: POST /players/ { "name": "Michael Jordan" } POST /teams/ { "name": "Chicago Bulls", "players": [1] } 然后,我收到以下回复: { "timestamp": "

我目前正在从事SpringBoot中的RESTAPI项目。我创建了两个实体——玩家和团队,它们通过一对多的关系联系在一起

基本上,问题是当我尝试创建新的玩家,然后创建新的团队并将玩家分配给它时。我做了以下工作:

POST /players/

{
   "name": "Michael Jordan"
}

POST /teams/

{
  "name": "Chicago Bulls",
  "players": [1]
}
然后,我收到以下回复:

{
    "timestamp": "2019-01-26T17:18:11.383+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "JSON parse error: Unresolved forward references for: ; nested exception is com.fasterxml.jackson.databind.deser.UnresolvedForwardReference: Unresolved forward references for: \n at [Source: (PushbackInputStream); line: 1, column: 43]Object id [1] (for `com.proglabs.nbaprojectrestapi.models.Player`) at [Source: (PushbackInputStream); line: 1, column: 41].",
    "path": "/teams/"
}
型号代码:

AbstractModel.java

import javax.persistence.*;

@MappedSuperclass
public abstract class AbstractModel {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    protected int id;

    @Column
    protected String name;

    // setters, getters...
}
Player.java

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import org.joda.time.LocalDate;

import javax.persistence.*;

@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "id",
        scope = Player.class)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@Entity
public class Player extends AbstractModel {

    @Column
    private LocalDate birthday;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Team team;

    // ...
}
Team.java

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;

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

@JsonIdentityInfo(
        generator = ObjectIdGenerators.PropertyGenerator.class,
        property = "id",
        scope = Team.class)
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@Entity
public class Team extends AbstractModel {

    @Column
    private int championships;

    @OneToMany(mappedBy = "team", fetch = FetchType.LAZY)
    private Set<Player> players = new HashSet<Player>();

    // setters, getters, other columns ...
}
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
导入com.fasterxml.jackson.annotation.JsonIgnoreProperties;
导入com.fasterxml.jackson.annotation.ObjectiveGenerators;
导入javax.persistence.*;
导入java.util.HashSet;
导入java.util.Set;
@JsonIdentityInfo(
生成器=ObjectedGenerators.PropertyGenerator.class,
property=“id”,
范围=团队(类)
@JsonIgnoreProperties({“HibernateLazInitializer”,“handler”})
@实体
公共类团队扩展了抽象模型{
@纵队
私人int锦标赛;
@OneToMany(mappedBy=“team”,fetch=FetchType.LAZY)
private Set players=new HashSet();
//setter、getter和其他列。。。
}
控制器代码:

AbstractController.java

import com.proglabs.nbaprojectrestapi.models.AbstractModel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.web.bind.annotation.*;

import java.util.List;

public abstract class AbstractController<T extends AbstractModel> {

    protected JpaRepository<T, Integer> repository;

    // ...

    @PostMapping("")
    public T create(@RequestBody T newEntity) {
        return repository.save(newEntity);
    }

    // ...
}
import com.proglabs.nbaprojectrestapi.models.AbstractModel;
导入org.springframework.data.jpa.repository.JpaRepository;
导入org.springframework.web.bind.annotation.*;
导入java.util.List;
公共抽象类抽象控制器{
受保护的JPA存储库;
// ...
@邮戳(“”)
public T create(@RequestBody T newEntity){
返回repository.save(newEntity);
}
// ...
}
TeamController/PlayerController(相关部件相同)

import com.proglabs.nbaprojectrestapi.models.Team;
导入com.proglabs.nbaprojectrestapi.repositories.TeamRepository;
导入org.springframework.web.bind.annotation.RequestMapping;
导入org.springframework.web.bind.annotation.RestController;
@RestController
@请求映射(“/teams”)
公共类TeamController扩展了AbstractController{
公共团队控制器(团队存储库){
this.repository=存储库;
}
// ...
}
我认为问题可能在于我对API应该如何设计的理解,但当我使用Jackson(没有Spring)将对象序列化/反序列化到json文件中/从json文件中序列化/反序列化时,我的方法工作得很好

如果有人给我指出正确的方向,我会非常感激。对不起,如果问题的提问方式不恰当


谢谢你抽出时间

我认为json需要对实体进行更紧密的建模。您是否尝试过发布类似这样的json

员额/小组/

{
    "name": "Chicago Bulls",
    "players": [
       {  "name": "Michael Jordan" },
       {  "name": "Joe Blogs" }  
    ]
}

我也会避免使用抽象类,直到它正常工作。嵌套类可能需要额外的精力来维护。

尝试将id构造函数添加到播放器:

public Player(int id) {
  this.id=id;
}

是的,你们说得对,这很有效,但若我想把球员分配到现有的球队呢?
public Player(int id) {
  this.id=id;
}