Spring JPA,Hibernate仅从其他实体获取PK或Ids

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring JPA,Hibernate仅从其他实体获取PK或Ids相关的知识,希望对你有一定的参考价值。

我有三个实体如下: 家长:

@Setter
@Getter
@Entity
public class Parent {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String parentName;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, targetEntity = Child.class)
    private List<Child> children;
}

儿童:

@Setter
@Getter
@Entity
public class Child {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String childName;

    @ManyToOne(targetEntity = Parent.class, cascade = CascadeType.MERGE)
    @JoinColumn(name = "parent_id")
    private Parent parent;

    @OneToMany(mappedBy = "child", cascade = CascadeType.ALL)
    private List<GrandChild> grandChildren;
}

如GrandChild:

@Getter
@Setter
@Entity
public class GrandChild {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @ManyToOne(cascade = CascadeType.MERGE, targetEntity = Child.class)
    @JoinColumn(name = "child_id")
    private Child child;
}

当我打电话给parentRepository.findById(id)时,我会得到一位父母带着孩子和孩子的大孩子。但是,这会导致2个问题:

  • 无限递归com.fasterxml.jackson.databind.JsonMappingException:因为所有实体都包含对彼此的引用。
  • 来自Hibernate的不必要的查询,因为我的ParentDto只包含List<Long> childrenIds

反正有没有让Hibernate从每个实体的引用中仅查询Id或PK而不是获取整个对象?就像是:

Parent: {
  "parentName" : "Parent Name",
  "children" : [ {
    "id" : 0
  }, {
    "id" : 1
  }, {
    "id" : 2
  } ]
}

或者:Parent: {"parentName" : "Parent Name", "childrenIds" : [0, 1, 2]}

答案

因此,给你一个parentId你想要检索parentName和只有相关的childIds -

而不是通过parentRepository,我宁愿在new method with @Query添加childRepository。方法和@Query如下:

@Query("select c.parent.id, c.parent.parentName, c.id from Child c where c.parent.id = ?1")

List<Object[]> findChildIdsByParentId(Long parentId);

每个对象[]将包含索引0处的parentId,索引1处的parentName和2处的childId。

获得此数据后,您可以在符合json格式的DTO(后来的jackson序列化)中填充此数据。

另一答案

关于第一个问题 - 为了避免无限递归,只需在每个'子'集合中添加注释@JsonIgnoreProperties,例如:

@JsonIgnoreProperties("parent")
private List<Child> children;

@JsonIgnoreProperties("child")
private List<GrandChild> grandChildren;

以上是关于Spring JPA,Hibernate仅从其他实体获取PK或Ids的主要内容,如果未能解决你的问题,请参考以下文章

Spring+Jersey+JPA+Hibernate+MySQL实现CRUD操作案例

Spring-data-jpa + Hibernate 未创建预期表

EAGER 和分页:Spring MVC + JPA Repository + Hibernate

仅从 Spring Data JPA 中的联接表(多对多)中选择特定列

将 Hibernate Sessions 功能与 Spring Data JPA 一起使用

Spring Data JPA / Hibernate中锁的范围是什么?