在读取具有一对多关系的JPA模型时生成不完整的JSON错误

时间:2017-11-18 13:00:56

标签: json jackson jax-rs eclipselink one-to-many

我正在使用JPA EclipseLink来模拟 UseCase PainPoint 之间的一对多关系。我能够很好地插入值。此后,我使用JAX-RS使用GET方法检索数据。 GET方法失败并显示错误 - 生成不完整的JSON

控制台日志:

  • [EL Fine]:INSERT INTO USECASE(UseCaseID,Description)VALUES(?,?) bind => [1,描述]
  • [EL Fine]:INSERT INTO PAIN_POINT (PainPointID,PainPointDescription,USECASE_ID)VALUES(?,?,?)绑定 => [2,痛点1,1]
  • [EL Fine]:SELECT UseCaseID,Description FROM USECASE
  • 2017年11月17日下午7:16:22 org.eclipse.yasson.internal.Marshaller marshall严重:生成 不完整的JSON

用例:

@NamedQueries({@NamedQuery(name = "getAllUseCases", query = "SELECT c FROM UseCase c")})

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@NotNull
@Column(name = "UseCaseID")
private int UseCaseID;

@Column(name = "Description")
private String Description;

@OneToMany(mappedBy="usecase", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
private Collection<PainPoint> painPoints = new ArrayList<PainPoint>();

PainPoint:

@NamedQueries({@NamedQuery(name = "getAllPainPoints", query = "SELECT c FROM PainPoint c")})

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@NotNull
@Column(name = "PainPointID")
private int PainPointID;

@Column(name = "PainPointDescription")
private String PainPointDescription;

@ManyToOne
@JoinColumn (name="USECASE_ID", referencedColumnName="UseCaseID")
private UseCase usecase;

的DataLoader:

UseCase useCase = new UseCase("Description 1");
PainPoint painPoint1 = new PainPoint("Pain Point 1", useCase);
useCase.getPainPoints().add(painPoint1);
em.persist(useCase);

UseCaseService:

@GET
@Path("/")
public List<UseCase> getUseCases() {

List<UseCase> retVal = null;

EntityManagerFactory emf = Utility.getEntityManagerFactory();
EntityManager em = emf.createEntityManager();

retVal = em.createNamedQuery("getAllUseCases").getResultList();

return retVal;
}

3 个答案:

答案 0 :(得分:5)

在循环引用的getter方法或任何其他派生字段上添加注释@JsonbTransient(package:javax.json.bind.annotation.JsonbTransient)。这相当于XML生成的@XmlTranisent注释,并将阻止转换为JSON进入无限循环。

我认为取决于您的工具集,但对于我使用NetBeans,当自动生成实体类时,会添加XML注释,但不会添加JSON。只需将每个@XmlTransient与等效的@JsonbTransient匹配

答案 1 :(得分:2)

根据以上Dale所说。您可以添加以下Maven依赖项

<dependency>
    <groupId>javax.json.bind</groupId>
    <artifactId>javax.json.bind-api</artifactId>
    <version>1.0</version>
</dependency>

有关@JsonbTransient的更多信息,请参见link

答案 2 :(得分:0)

这很可能是由 Circular Reference 引起的。Json and Java - Circular Reference中描述了两种处理此问题的方法:

  
      
  1. @JsonIgnore
  2.   
  3. @JsonManagedReference和@JsonBackReference
  4.   

我建议您采用第二种方法,并将这两个注释添加为两个,以避免循环引用问题:

@OneToMany(mappedBy="usecase", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JsonBackReference                ///// ADD THIS ANNOTATION
private Collection<PainPoint> painPoints = new ArrayList<PainPoint>();


@ManyToOne
@JoinColumn (name="USECASE_ID", referencedColumnName="UseCaseID")
@JsonManagedReference              ///// ADD THIS ANNOTATION
private UseCase usecase;

更多信息: