读取具有一对多关系的JPA模型时生成不完整的JSON错误
我正在使用JPA EclipseLink对用例和PainPoint之间的一对多关系进行建模。我可以很好地插入值。此后,我使用JAX-RS使用GET方法检索数据。GET方法失败,错误为生成不完整的JSON 控制台日志:读取具有一对多关系的JPA模型时生成不完整的JSON错误,json,jackson,jax-rs,eclipselink,one-to-many,Json,Jackson,Jax Rs,Eclipselink,One To Many,我正在使用JPA EclipseLink对用例和PainPoint之间的一对多关系进行建模。我可以很好地插入值。此后,我使用JAX-RS使用GET方法检索数据。GET方法失败,错误为生成不完整的JSON 控制台日志: @NamedQueries({@NamedQuery(name = "getAllUseCases", query = "SELECT c FROM UseCase c")}) @Id @GeneratedValue(strategy = GenerationType.AUTO)
@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>();
@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;
UseCase useCase = new UseCase("Description 1");
PainPoint painPoint1 = new PainPoint("Pain Point 1", useCase);
useCase.getPainPoints().add(painPoint1);
em.persist(useCase);
@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;
}
- [EL Fine]:在用例(UseCaseID,描述)中插入值(?,) 绑定=>[1,说明]
- [EL Fine]:插入痛点 (PainPointID,PainPointDescription,USECASE_ID)值(?,?)绑定 =>[2,痛点1,1]
- [EL Fine]:选择UseCaseID,从USECASE中选择描述
- 2017年11月17日下午7:16:22 org.eclipse.yasson.internal.Marshaller:Generating 不完全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>();
@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;
UseCase useCase = new UseCase("Description 1");
PainPoint painPoint1 = new PainPoint("Pain Point 1", useCase);
useCase.getPainPoints().add(painPoint1);
em.persist(useCase);
@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;
}
数据加载器:
@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>();
@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;
UseCase useCase = new UseCase("Description 1");
PainPoint painPoint1 = new PainPoint("Pain Point 1", useCase);
useCase.getPainPoints().add(painPoint1);
em.persist(useCase);
@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;
}
UseCaseService:
@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>();
@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;
UseCase useCase = new UseCase("Description 1");
PainPoint painPoint1 = new PainPoint("Pain Point 1", useCase);
useCase.getPainPoints().add(painPoint1);
em.persist(useCase);
@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;
}
@GET
@路径(“/”)
公共列表getUseCases(){
列表retVal=null;
EntityManagerFactory emf=Utility.getEntityManagerFactory();
EntityManager em=emf.createEntityManager();
retVal=em.createNamedQuery(“getAllUseCases”).getResultList();
返回返回;
}
在循环引用的getter方法或任何其他派生字段上添加注释@jsonbttransient(包:javax.json.bind.annotation.jsonbttransient)。这相当于用于XML生成的@XmlTranisent注释,并将防止转换为JSON进入无限循环
我想这取决于您的工具集,但对于使用NetBeans的我来说,当自动生成实体类时,会添加XML注释,但不会添加JSON注释。根据上面所说的,只需将每个@xmltransive与等效的@JsonbTransient进行匹配即可。您可以添加以下Maven依赖项
<dependency>
<groupId>javax.json.bind</groupId>
<artifactId>javax.json.bind-api</artifactId>
<version>1.0</version>
</dependency>
javax.json.bind
这很可能是由循环引用引起的,有两种方法处理此问题,如中所述:
@杰索尼奥雷
@JsonManagedReference和@JsonBackReference
我建议您采用第二种方法,并添加以下两种注释,以避免循环引用问题:
@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;
@OneToMany(mappedBy=“usecase”,cascade=CascadeType.ALL,fetch=FetchType.EAGER)
@JsonBackReference//添加此批注
private Collection painPoints=new ArrayList();
@许多酮
@JoinColumn(name=“USECASE\u ID”,referencedColumnName=“UseCaseID”)
@JsonManagedReference///添加此批注
私人用例用例;
更多信息:
@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>();
@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;
UseCase useCase = new UseCase("Description 1");
PainPoint painPoint1 = new PainPoint("Pain Point 1", useCase);
useCase.getPainPoints().add(painPoint1);
em.persist(useCase);
@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;
}
显然,JSON生成与JPA API无关,所以为什么不调试到JSON生成的位置,使用什么代码……我想我应该在原始帖子中包含这些信息。但似乎有某种循环递归搜索正在进行。例如,用例有痛点。PainPoint与用例相关联。所以JSON出现了错误。。。不知道如何在一对多关系中绕过它。我删除了引用用例的PainPoint对象上的getter和setter,现在它似乎可以工作了。哈哈,应该猜到了。希望我不会遇到其他问题。我使用了来自和works的@JsonIdentityInfo,谢谢。@AndréLuítomaszdio我很高兴它对您有所帮助。