2012-03-27 51 views
0

我正在编写一个Web应用程序(Tomcat 7),因此没有JTA,并且想要显示项目列表,包括与JSF页面中每个项目关联的任务。在JSF中使用实体

有2个实体 - 包含任务集合的项目。从我的Managed Bean中,我调用一个方便的方法来检索所有活动的项目,然后在此项目集合上进行迭代(ui:repeat),并希望显示每个项目的任务。当我尝试这样做时,我得到一个持久性异常,因为持久性上下文不在范围之内。

没有创建项目和任务的支持bean,也没有使用扩展上下文我有什么其他选项。

回答

0

让您方便的方法也取任务,例如通过在查询中加入该关联?如果任务已经加载,JPA在访问集合时将不需要获取它们。

编辑:JPA 2.0 specification写入在第4.4.5.3:

甲FETCH JOIN使得能够缔合或元素集合作为一个查询的执行的副作用的取出。

的语法要抓取联接是

fetch_join ::= [ LEFT [OUTER] | INNER ] JOIN FETCH join_association_path_expression 

由FETCH JOIN子句的右侧引用必须是关联或元件的集合,从该返回为一个实体或嵌入引用的关联查询的结果。

不允许为FETCH JOIN子句右侧引用的对象指定标识变量,因此对隐式提取的实体或元素的引用不能出现在查询的其他位置。

以下查询返回一组部门。作为副作用,还会检索这些部门的相关员工,即使他们不是显式查询结果的一部分。由于获取连接而检索的对象的持久状态或关系字段或属性的初始化由该类的元数据确定 - 在本示例中为Employee实体 类。

SELECT d 
FROM Department d LEFT JOIN FETCH d.employees 
WHERE d.deptno = 1 

甲取加入了同一连接的语义相应的内或外连接,不同之处在于上的连接操作的右手侧所指定的相关对象未在查询结果返回的或以其他方式中引用查询。因此,例如,如果部门1有五名员工,则上述查询将返回五个对部门1实体的引用。

不得在子查询的FROM子句中使用FETCH JOIN构造。

+0

我该如何编写查询以便JPA加载相关数据?现在我的查询只是“SELECT p FROM project p”。 – semiintel 2012-03-28 09:40:13

+0

我的答案现在包含规范的相关部分,根据您的需求调整其包含的示例应该很简单。 – meriton 2012-03-28 19:54:46

+0

太棒了,实际上只是在阅读文章。谢谢你回来更新答案。 – semiintel 2012-03-28 20:28:30

0

手动打开EntityManager(使用工厂)并启动事务,然后提交并关闭实体管理器。

但是,这不是一个很好的选择 - 看看像CDI,接缝或Spring来管理事务和会话你(如果你不希望使用EJB3)

1

经过一番更多的思考和研究,我已经回过头来正确描述我所处的情况,然后也提供了解决问题的方法。

发生的事情是Project实体具有指定为Lazy Loaded的任务关系。 JPA使用代理对象在请求获取数据之前等待集合的请求。这成为一个问题,因为我们试图在Persistent上下文分离实体后访问信息。

分辨率:

触发延迟加载 - 尽管持久性上下文还是在范围上调用集合getter和任何其他的方法你想的数据,这触发了对数据加以取出,并添加该实体。

使提取类型Eager - 查看使用延迟加载并将提取类型更改为渴望的原因。 “FetchType.EAGER”

Fetch Joints - 将关联添加为与查询一起提取的JP QL的一部分。这优化了查询和关联在一次调用中加载,同时仍然只返回单个实体。 “SELECT p FROM Project p LEFT JOIN FETCH p.tasks”

希望这可以帮助下一个人找到解决方案。