Hibernate懒惰的获取 - 获取子对象

时间:2017-08-08 14:20:16

标签: java hibernate spring-boot spring-data-jpa

我的理解是,默认情况下,对于所有关系类型,Hibernate都会将FetchType设置为lazy。

在我的情况下,我有一个双向的OneToMany-ManyToOne关系,如下所示:

家长班:

public class Parent{

    @Id
    @Column(name = "parent_id")
    private long parentId;

    @OneToMany(mappedBy = "parent")
    @JsonIgnore
    private List<Child> children;

    public List<Child> getChildren()
    {
        return this.children;
    }
}

儿童班:

public class Child
{
    private String name;

    @ManyToOne(optional = false) //every child must have a parent
    @JoinColumn(name = "parent_id")
    private Parent parent;

    public Child(Parent parent, String name)
    {
        this.parent = parent;
        this.name = name;
    }
}

儿童服务:

public class ChildService
{
    public List<Child> getChildren(long parentId)
    {
        Parent parent = getParentRepository().findOne(parentId);
        return parent.getChildren(); //This returns null
    }

    public Child getNamedChild(long parentId)
    {
        Parent parent = getParentRepository().findOne(parentId);
        //??????????????? 
        //Not sure how to get the children of this specific parent, 
        //which has a specific name.
    }
}

父存储库:

public interface ParentRepository extends JpaRepository<Parent, Long> {
}

我有两个问题:

当我在ChildService中调用方法getChildren()时,它返回null。数据库确实包含正确的数据。 我将需要使用LAZY fetch类型获取这些。 我试图调用一个&#34; parent.getChildren()。size()&#34;返回之前的方法,但它仍然返回null。

另一个问题是如何让孩子拥有特定的名字?是否可以通过存储库执行此操作?或者我需要getChildren(parentId),并迭代直到找到以特定方式命名的那个?

编辑: 在提出一些建议之后,我继续以这种方式实现了我的ChildRepository:

public interface ChildRepository extends JpaRepository<Child, Long> {
    @Query("SELECT child FROM Parent parent JOIN parent.child AS child WHERE parent.parentId = :parentId")
    List<Child> getChildren(@Param("parentId") String parentId);
    @Query("SELECT child FROM Parent parent JOIN arent.child AS child WHERE parent.parentId = :parentId AND child.childId = :childId")
    Child getChildByName(@Param("childId") Long childId, @Param("parentId") String parentId);
}

1 个答案:

答案 0 :(得分:1)

您可以在ChildService类中注入EntityManager吗?我无法完全验证下面的代码,但您可以尝试类似

的内容
public class ChildService
{
    private EntityManager em;

    public List<Child> getChildren(long parentId)
    {
        Query query = em.createQuery("SELECT c FROM Parent p JOIN FETCH p.children AS c WHERE p.parentId = :parentId");
        query.setParameter("parentId", parentId);
        return (List<Child>) q.getResultList();
    }

    public Child getNamedChild(long parentId, String name)
    {
        Query query = em.createQuery("SELECT c FROM Parent p JOIN FETCH p.children AS c WHERE p.parentId = :parentId AND c.name = :name");
        query.setParameter("parentId", parentId);
        query.setParameter("name", name);
        return (Child) q.getSingleResult();
    }

}