我在一个使用SpringBoot2.0、Hibernate和SpringDataREST的项目中工作。前端带有React
我遇到过这样的情况:一个用户可以与多家公司(他拥有多家公司)链接
当我尝试使用UserRepository或CompanyRepository获取一些实体时,我得到了错误:无法写入JSON:Infinite recursion(StackOverflowerError);嵌套的异常是com。fasterxml。杰克逊。数据绑定。JsonMappingException:无限递归(StackOverflowerr)
我必须使用投影来限制数据进入前端,因为我需要由投影自动生成的实体链接。
遵循实体:
@Entity
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_user")
protected Long id;
@OneToMany(cascade= { CascadeType.MERGE }, fetch = FetchType.EAGER, mappedBy="user")
private List<Company> companyList;
// Other data
// Getters and Setters
}
@Entity
public class Company extends CadastroEmpresaUnica {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id_company")
protected Long id;
@ManyToOne(cascade= { CascadeType.MERGE })
@JoinColumn(name="id_user", nullable = false)
private User user;
// Other data
// Getters and Setters
}
预测:
@Projection(name = "userProjection", types = { User.class })
public interface UserProjection {
List<CompanyProjection> getCompanyList();
// Other Getters
}
@Projection(name = "companyProjection", types = { Company.class })
public interface CompanyProjection {
UserProjection getUser();
// Other Getters
}
我们正在使用的存储库之一:
@RepositoryRestResource(collectionResourceRel = "company", path = "companies", excerptProjection = CompanyProjection.class)
public interface CompanyRepository extends PagingAndSortingRepository<Company, Long>, CompanyRepositoryCustom, JpaSpecificationExecutor<Company> {}
在搜索双向无限递归时,我发现了关于@JsonManaged参考和@JsonBack参考的内容,这些内容总是直接在实体中使用。所以我试着在我的投影中使用,它起作用了。所以它解决了我的无限递归问题,但是它产生了另一个问题,我不能从我的公司访问我的用户(因为显然“@JsonBack参考”不能让它停止递归)。
这是我的投影与这个解决方案:
@Projection(name = "userProjection", types = { User.class })
public interface UserProjection {
@JsonManagedReference
List<CompanyProjection> getCompanyList();
// Other Getters
}
@Projection(name = "companyProjection", types = { Company.class })
public interface CompanyProjection {
@JsonBackReference
UserProjection getUser();
// Other Getters
}
搜索多一点,我读到'@JsonIdtyInfo',再次,在实体中使用。所以我试图删除其他Json注释,并在我的投影中使用@JsonIdtyInfo。如下例所示:
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="id")
@Projection(name = "userProjection", types = { User.class })
public interface UserProjection {
Long getId();
List<CompanyProjection> getCompanyList();
// Other Getters
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property="id")
@Projection(name = "companyProjection", types = { Company.class })
public interface CompanyProjection {
Long getId();
UserProjection getUser();
// Other Getters
}
它不起作用。现在Json无限递归再次发生
我是SpringDataREST新手,我正在阅读SpringDocumentation和Stackoverflow主题,试图更好地理解SpringDataREST的投影。我想知道我做错了什么,当然,如果我以错误的方式使用投影,但是我需要继续这个项目。
我们找到的最好的方法是使用Jackson注释@JsonIgnoreProperties,它应该在父列表中使用,以便在子列表中显示自己。但是,经过几次尝试之后,这个注释似乎在投影中不起作用,特别是在Spring数据REST中
按照正确方法的示例进行操作:
@Projection(name = "userProjection", types = { User.class })
public interface UserProjection {
@JsonIgnoreProperties({"user"})
List<CompanyProjection> getCompanyList();
// Other Getters
}
@Projection(name = "companyProjection", types = { Company.class })
public interface CompanyProjection {
UserProjection getUser();
// Other Getters
}
我们发送了一张关于这个Spring数据REST问题的票证,它已经被接受。我们相信在不久的将来,它将得到纠正,我们可以使用它
现在,我们调整投影,以便列表对象可以使用原始投影的“派生”,忽略导致无限递归的属性
遵循以下示例:
@Projection(name = "userProjection", types = { User.class })
public interface UserProjection {
List<CompanyProjectionWithoutUser> getCompanyList();
// Other Getters
// Projection without the User, that couses infinite recursion
public interface CompanyProjectionWithoutUser extends CompanyProjection {
@Override
@JsonIgnore
UserProjection getUser();
}
}
@Projection(name = "companyProjection", types = { Company.class })
public interface CompanyProjection {
UserProjection getUser();
// Other Getters
}
有点难看,但简单的解决方案可能是再进行一次投影(例如,CompanyWithoutUserProjection),这可以停止递归。
CompanyProjection {
UserProjection getUser();
//other getters
}
UserProjection {
List<CompanyWithoutUserProjection> getCompanyList();
//other getters
}
CompanyWithoutUserProjection {
//other getters
}
首先,SDR不喜欢双向关系
要解决这种情况,请尝试在公司实体中的User getter中添加以下内容:
@RestResource(exported = false)
@JsonIgnore
public User getUser() {...}
您也可以尝试使用注释@JsonIgnoreProperties。
此外,我认为如果你只需要得到用户的公司(和公司的用户),你不需要使用预测。SDR中的关联资源按如下方式导出(在您的示例中):
/users/{id}/companies
/companies/{id}/users
首先,这是我的实体。 玩家: 团队: 正如已经说明的许多主题一样,您可以通过Jackson以多种方式避免WebService中的StackOverflow Exeption。 这很酷,除了JPA之外,在序列化之前,所有的实体都可以无限递归地构造另一个实体。这只是丑陋的ans请求需要更长的时间。检查这个截图:IntelliJ调试器 有办法解决吗?知道我希望根据endpoint获得不同的结果。示例:
我用的是Spring Roo 1.2.1和Jackson 1.9.7。在使用json序列化我的类时,我得到了一个JsonMappingException。 我读了以下帖子,但没有找到适合我的工作解决方案: Jackson的无限递归 Jackson-具有双方向关系的实体序列化(避免循环) 我不知道为什么JsonIgnore在属性QueueOuts的类Queue中不起作用。我也尝试了JsonManag
问题内容: 我使用Gson 库将Java对象转换为Json响应…问题是,在JPA请求之后,由于与其他实体的递归关系,无法转换从DB检索到的对象: 我的源代码: 如您在这里看到的,我做了: 只是通过为coordonneesList中的每个GPS对象设置null来消除递归关系。 您认为这是一个很好的解决方案,或者还有其他更实用的方法吗?谢谢 问题答案: 有一个名为GraphAdapterBuilder
我在和之间具有双向多对多关系。在的帮助下创建两个实体,甚至创建它们的子实体都是简单明了的。 和都可以在的帮助下轻松地自动持久化,如下所示: 然而...更新会导致异常: 我尝试修改的以包括、和/或,但未成功。我们怎么绕过这件事?
在尝试执行GET到发布者存储库时,我正在执行GET和无限循环。 出版商: 书: 完整代码可在此处获得: https://github.com/vanyasav/library
我在谷歌上搜索过,找不到任何可以在O(1)时间内存储和读取双向数据的DS。例如书籍和作家。有了书的名字,就必须找到作者。有了作者的名字,就必须找到书。 在数据库中,这些关系(如联接表)是如何存储的? 提前谢谢。