将 Spring JPA 一对多对象编组为 JSON

Marshalling Spring JPA one to many objects into JSON

我正在尝试将 3 个 JPA 对象编组为 JSON 字符串。 Game 对象包含一个玩家列表,每个玩家都包含一个帧列表。 JPA 部分似乎工作正常。但是,JSON 输出为空。

Game.java

package com.bowling.bowlingapp.game;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

/**
 * A single bowling game
 *
 */
@Entity
@Table( name = "games")
public class Game {

     @Id @GeneratedValue
     @JsonIgnore
     private Long id;

     @OneToMany(cascade = CascadeType.ALL,
             fetch = FetchType.LAZY,
             mappedBy = "game")
     @JsonManagedReference
     List<Player> players;

     public List<Player> getPlayers() {
          return players;
     }

     public void setPlayers(List<Player> players) {
          this.players = players;
     }

     public void addPlayer(Player player) {
          if (this.players == null) {
               players = new ArrayList<>();
          }
          this.players = players;
     }
}

Player.java

package com.bowling.bowlingapp.game;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import javax.persistence.*;
import java.util.List;

/**
 * A bowler
 *
 */
@Entity
@Table(name = "players")
public class Player {

    @Id
    @GeneratedValue
    @JsonIgnore
    private Long id;

    @Column
    private String name;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "game_id", nullable = false)
    @JsonBackReference
    private Game game;

    @OneToMany(cascade = CascadeType.ALL,
            fetch = FetchType.LAZY,
            mappedBy = "player")
    @JsonManagedReference
    List<Frame> frames;

    public Player(String name) {
        this.name = name;
    }

    public void setFrames(List<Frame> frames) {
        this.frames = frames;
    }
}

Frame.java

package com.bowling.bowlingapp.game;

import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import javax.persistence.*;

/**
 * an object representing a frame.
 * Each value will be -1 until set
 *
 */
@Entity
@Table(name = "frames")
public class Frame {

    @Id
    @GeneratedValue
    private Long id;

    @Column
    private int firstRoll = -1;
    @Column
    private int secondRoll = -1;
    //3rd roll for tenth frame
    @Column
    private int thirdRoll = -1;
    @Column
    private int score = -1;

    @JsonIgnore
    private final static int NUMBER_OF_PINS=10;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "player_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    @JsonBackReference
    private Player player;
   
    public void setScore(int score) {
        this.score = score;
    }

}

我正在尝试使用以下代码将其编组:

public String makeGame() {

        Player bob = new Player("Bob");
        Player joe = new Player("Joe");
        Frame frameOne = new Frame();
        frameOne.setScore(12);
        Frame frameTwo = new Frame();
        frameTwo.setScore(15);
        List<Frame> frames = new ArrayList<>();
        bob.setFrames(frames);
        joe.setFrames(frames);

        List<Player> players = new ArrayList<>();
        players.add(bob);
        players.add(joe);
        Game game = new Game();
        game.setPlayers(players);

        ObjectMapper mapper = new JsonMapper();
        String result = "temp";
        try {
            result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(game);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        return result;

    }

但是我的输出是这样的:

{
"players" : [
    { 
      "frames" : [ ] 
    }, 
    { "frames" : [ ] 
    } 
    ]
}

如您所见,它是空的。我做错了什么?

编辑:现在我为每个私有属性添加了 getter 和 setter,输出如下所示:

{
"players" : [ {
"name" : "Bob",
"frames" : [ ]
}, {
"name" : "Joe",
"frames" : [ ]
} ]

编辑:我忘记将 frames.add(frameOne); frames.add(frameTwo); 添加到我的生成器代码中。现在可以了。谢谢!

Object Mapper在幕后使用了所有属性的getter方法。 请在所有 3 类.

中声明 getter 方法