春天休息产生重复的json

时间:2016-02-15 15:01:36

标签: json spring rest duplicates

我有一个简单的Q& A应用程序我正在试验它有三个类测验,问题和答案。基本关系如下:

@Entity
public class Quiz {

    @Id
    @GeneratedValue

    private Long id; 

    private String description;

     @OneToMany(cascade=CascadeType.PERSIST, fetch=FetchType.EAGER)
     private List<Question> questions = new ArrayList<>();

@Entity
public class Question {

    @Id
    @GeneratedValue

    private Long id;

    private String description;

    @ElementCollection(fetch=FetchType.EAGER)
    private List<Answer> answers;

@Embeddable
public class Answer {


    private String description;
    private boolean correct;

正确加载JPA /数据库时,单个测验包含一个问题,其中包含三个答案。但是,返回的相应JSON具有大量重复数据。

{
  "id" : 1,
  "description" : "Intro to Spring 4",
  "questions" : [ {
    "id" : 1,
    "description" : "What is Spring?",
    "answers" : [ {
      "description" : "A season",
      "correct" : false
    }, {
      "description" : "A coily wire",
      "correct" : false
    }, {
      "description" : "A wonderful framework",
      "correct" : true
    } ]
  }, {
    "id" : 1,
    "description" : "What is Spring?",
    "answers" : [ {
      "description" : "A season",
      "correct" : false
    }, {
      "description" : "A coily wire",
      "correct" : false
    }, {
      "description" : "A wonderful framework",
      "correct" : true
    } ]
  }, {
    "id" : 1,
    "description" : "What is Spring?",
    "answers" : [ {
      "description" : "A season",
      "correct" : false
    }, {
      "description" : "A coily wire",
      "correct" : false
    }, {
      "description" : "A wonderful framework",
      "correct" : true
    } ]
  } ]
}

有人看到任何明显的东西吗?我正在使用Jackson mapper。

3 个答案:

答案 0 :(得分:2)

您应该使用Set代替问题和答案,而不是List。此外,您的实体应覆盖equals()hashCode(),以便它们通过id属性实现相等。

关于列表包含重复项的原因an explanation is given here。简而言之,它声明向数据库发出SQL外连接,外连接确实产生重复结果。

摘录:

  

首先,您需要了解SQL以及OUTER JOIN在SQL中的工作方式。如果您不完全理解和理解SQL中的外连接,请不要继续阅读此FAQ项,而是查阅SQL手册或教程。否则你将无法理解以下解释,你会在Hibernate论坛上抱怨这种行为。

     

(...)

     

想知道重复的原因在哪里?查看SQL结果集,Hibernate不会在外部联接结果的左侧隐藏这些重复项,但会返回驱动表的所有重复项。如果数据库中有5个订单,并且每个订单有3个订单项,则结果集将为15行。这些查询的Java结果列表将包含15个元素,所有元素都是Order。 Hibernate只会创建5个Order实例,但SQL结果集的重复项将保留为对这5个实例的重复引用。如果您不理解最后一句,您需要阅读Java以及Java堆上的实例与对此类实例的引用之间的区别。

虽然链接和说明适用于Hibernate,但JPA可以观察到相同的行为。

答案 1 :(得分:0)

在getter方法中注入@JsonProperty(“ yourFiledName”)对我有用。

@Entity
public class Quiz {

    @Id
    @GeneratedValue

    private Long id; 

    private String description;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
   @JsonProperty("description")
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

/ **对问题实体类别做相同的事情** /

注意:@JsonPropertiy来自Jackson库。对于Maven用户,以下是依赖项

       <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.9.6</version>
        </dependency>

答案 2 :(得分:0)

仅针对那些在此问题上苦苦挣扎的人。刚设定 @ElementCollection(fetch=FetchType.EAGER)@ElementCollection(fetch=FetchType.LAZY)

这解决了我的问题!