我的理解是,默认情况下,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> {
}
另一个问题是我如何得到一个有特定名字的孩子?是否可以通过存储库进行操作?还是需要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);
}
可以在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();
}
}
我试着调整我的应用程序,所以我把关系变成懒惰的,只取我需要的东西 我的多对一关系有一个问题,当我再次加载实体时转到lazy时,Hibernate将实体替换为代理,即使我获取了该实体,而该代理在应用程序的视图部分(JSF)中不工作。当多对一处于急切模式时,问题就会消失,但hibernate会为每个多对一执行一个select more(选择更多),即使我不需要它们 1/ 2/ JPQL查询: =>两次
我有两个大表(每个表>一亿行),让我们把它们称为Parent和Child(Parent与Child有一个懒散的一对多关系)。当我使用联接提取时,查询速度非常慢,而且我还得到一个Hibernate警告“HH000104 firstresult maxresults specified with collection fetch Application in Memory”,因为我使用了一个限制。 因
我有一个简单的查询很好地工作了一段时间,现在我将代码中的一些内容改为: (hibernate.cfg.xml) 和以下代码: 提交后,result对象不会加载列表(即从开始) 如果我执行在提交前,它会保持加载状态,而且,如果我使用它工作得很好。(但这不是它应该如何工作(让它在使用时打开并加载),createAlias应该一如既往地正常工作) 看起来DetachedCriteria的createAl
当然,这些列表有setter和getter。现在我想实现以用户身份不参加这些事件的可能性。因此,我尝试了以下方法: 我得到的例外情况如下: 尽管我使用了一些方法来确保执行惰性提取:
考虑以下实体: 的应该被延迟获取。问题是,当使用