Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Hibernate(JPA)如何进行急切查询,加载所有子对象_Java_Hibernate_Jpa_Ejbql - Fatal编程技术网

Java Hibernate(JPA)如何进行急切查询,加载所有子对象

Java Hibernate(JPA)如何进行急切查询,加载所有子对象,java,hibernate,jpa,ejbql,Java,Hibernate,Jpa,Ejbql,关于my,我希望确保加载所有子对象,因为我有多个线程可能需要访问数据(从而避免延迟加载异常)。我知道这样做的方法是在查询中使用“fetch”关键字(ejbql)。像这样: select distinct o from Order o left join fetch o.orderLines 假设模型中有一个订单类,该类中有一组订单行 我的问题是,似乎需要使用“distinct”关键字,否则我似乎会为每个订单行返回一个订单。我做的对吗 也许更重要的是,是否有一种方法可以拉入所有子对象,无论其深度

关于my,我希望确保加载所有子对象,因为我有多个线程可能需要访问数据(从而避免延迟加载异常)。我知道这样做的方法是在查询中使用“fetch”关键字(ejbql)。像这样:

select distinct o from Order o left join fetch o.orderLines
假设模型中有一个
订单
类,该类中有一组
订单行

我的问题是,似乎需要使用“distinct”关键字,否则我似乎会为每个
订单行
返回一个
订单
。我做的对吗


也许更重要的是,是否有一种方法可以拉入所有子对象,无论其深度如何?我们有大约10-15个类,对于服务器,我们需要加载所有内容。。。我一直在避免使用FetchType.EAGER,因为这意味着它总是渴望的,尤其是web前端加载所有东西——但也许这就是方法——你就是这么做的吗?我似乎记得我们以前尝试过这个方法,然后得到了非常慢的网页-但也许这意味着我们应该使用二级缓存?

我不确定是否要在EJBQL中使用fetch关键字,您可能会将其与注释混淆

您是否尝试将FetchType属性添加到关系属性中

@OneToMany(fetch=FetchType.EAGER)

见:


这只适用于多通关系,对于它们@ManyToOne(fetch=FetchType.EAGER)可能是合适的


急切地获取多个OneToMany关系是不被鼓励和/或不起作用的,正如您在Jeremy发布的链接中所看到的那样。只需考虑执行此类获取所需的SQL语句…

在我看来,更改注释是一个坏主意,因为它不能在运行时更改为lazy。最好让一切都变得懒惰,并根据需要取回


我不确定我是否理解没有映射的问题。对于所描述的用例,应该只需要左连接获取。当然,如果orderline有一个order作为其父对象,那么您将获得每个orderline的订单。

我所做的是重构代码,以保留对象到实体管理器的映射,每次需要刷新时,关闭对象的旧entitymanager并打开一个新的。我使用上面的查询时没有使用fetch,因为这对我的需求来说太深了-只需在订单行中进行简单的连接-使用fetch会使查询更深入

我只需要为几个对象使用它,大约20个,所以我认为拥有20个OpenEntityManager的资源开销不是问题——尽管DBA在使用时可能会有不同的看法

我还重新处理了一些事情,以便db工作在主线程上,并具有实体管理器


Chris

如果问题只是LazyInitializationExceptions,您可以通过添加OpenSessionInViewFilter来避免它。
这将允许在视图中加载对象,但无助于解决速度问题

     <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

冬眠过滤器
org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
冬眠过滤器
/*

您可以使用(分离的)条件查询并设置获取模式来执行类似操作。例如:

Session s = ((HibernateEntityManager) em).getSession().getSessionFactory().openSession();
DetachedCriteria dc = DetachedCriteria.forClass(MyEntity.class).add(Expression.idEq(id));
dc.setFetchMode("innerTable", FetchMode.JOIN);
Criteria c = dc.getExecutableCriteria(s);
MyEntity a = (MyEntity)c.uniqueResult();

您是否尝试过使用结果转换器?如果使用条件查询,则可以应用结果转换器(尽管):

em.getDelegate()
是一种只有在使用hibernate时才有效的黑客攻击

也许更重要的是,是否存在 拉入所有子对象的方式,否 不管有多深?我们大约有10-15个 类和服务器,我们将 需要加载所有内容。。。我是 避免使用FetchType.EAGER 意味着它总是渴望和投入 web前端负载的特殊情况 一切——但也许这就是问题所在 干得好-你就是这么做的吗?我 好像记得我们以前试过这个 然后是速度非常慢的网页 -但也许这意味着我们应该使用二级缓存

如果你仍然感兴趣,我在这个帖子中回答了一个类似的问题


基本上,您使用一个名为的实用程序将bean映射到另一个bean上,通过这样做,您将触发所有的延迟加载。正如你所想象的,如果所有的集合都被急切地抓取,这会更好。

谢谢,但这个答案与webapps/servlet有关,而不是我正在使用的独立应用程序。谢谢,但问题是我想在拥有EM的主线程之外使用持久化对象,获取有关事物当前状态的瞬态数据。因此,我不能使用主EM,但也需要相同的对象:(这家伙需要在运行时更改策略。“最好让一切都变懒,并根据需要获取。”-100%同意。
Criteria c = ((Session)em.getDelegate()).createCriteria(Order.class);
c.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
c.list();