我的理解是,默认情况下,对于所有关系类型,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);
}
答案 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();
}
}