0

我正在尝试使用 Vaadin 和 JPA Persistence 层做一个简单的概念证明。

我有一个与 fetchType = Lazy 有@OneToMany 关系的 Bean,当我尝试使用我的 DAO 将这些 bean 的集合添加到表中时。我有下一个例外:

Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: common.domain.Bill.detail, no session or session was closed

有没有办法在没有 JPAContainer 的情况下使用 Vaadin 和 JPA?

谢谢。

4

3 回答 3

0

您可以使用 Bean(Item)Container 并在那里添加您的实体。

如果你只使用一个容器,你就没有像使用 JPAContainer 那样的延迟加载了。

使用容器的组件仍然会从容器中进行延迟加载,但所有对象都保存在容器中。然后必须自己完成容器的延迟加载。

有关 Bean(Item)Container 和 Containers 的更多信息,请点击此处

于 2012-07-07T21:07:45.183 回答
0

这是一个旧帖子,但是...

让我们看看您的用例:
-您的浏览器请求您的应用程序
-在您的服务器端代码中,您使用 EntityManager 加载 bean(您的 bean 在会话中),但它的关系实例(它是惰性的)是代理 => 关系实例只会在您第一次访问它时加载
- 您的浏览器收到响应
- 您单击一个按钮(例如)向服务器发送请求
- 您尝试添加/更改某些内容到惰性关系
- 如代理没有会话(它是使用前一个会话创建的,但现在它不再附加到它也不是会话),它会引发异常

您可以尝试以下解决方案之一:
1-尝试合并您的 bean(将 bean 附加到当前会话):bean = em.merge(bean);就在添加/更改惰性关系之前
2-尝试在加载实体时强制加载惰性关系第一次:bean.getMyLazyRelationship();
3-在修改之前再次加载您的实体
4-将 LAZY 更改为 EAGER,但它(通常)不是一个好的解决方案

使用容器可能会可能不会解决这个问题。

希望能帮助到你

于 2013-03-18T13:21:22.970 回答
0

我正在使用来自lazyquerycontainer插件的EntityContainer 类。顾名思义,它支持延迟加载。它只是工作:)

一些示例代码:

    resultsTable = new Table();

    resultsTable.setSelectable(true);
    resultsTable.setCaption("JpaQuery");
    resultsTable.setPageLength(40);
    resultsTable.setImmediate(true);
    resultsTable.setEditable(false);
    resultsTable.setWriteThrough(true);

    container = new EntityContainer<Call>(em, false, true, true, Call.class, 100, new Object[] {"imsi"}, new boolean[] {true});

    container.addContainerProperty(LazyQueryView.PROPERTY_ID_ITEM_STATUS, QueryItemStatus.class, QueryItemStatus.None, true, false);
    container.addContainerProperty("startTime", Date.class, null, true, true);
    container.addContainerProperty("stopTime", Date.class, null, true, true);
    container.addContainerProperty("imsi", String.class, null, false, true);
    container.addContainerProperty("imei", String.class, null, false, true);
    container.addContainerProperty("callType", Integer.class, null, true, true);
    container.addContainerProperty("cdpn", String.class, null, true, true);
    container.addContainerProperty("cgpn", String.class, null, true, true);
    container.addContainerProperty("status", Integer.class, null, true, true);
    container.addContainerProperty("mmRelCause", Integer.class, null, true, true);
    container.addContainerProperty("rrRelCause", Integer.class, null, true, true);

    resultsTable.setContainerDataSource(container);

    resultsTable.setVisibleColumns(new String[] {"startTime" , "stopTime" , "imsi", "imei", "callType" , "cdpn", "cgpn", "status", "mmRelCause"      , "rrRelCause" });
    resultsTable.setColumnHeaders(new String[]  {"Start time", "Stop time", "IMSI", "IMEI", "Call Type", "CDPN", "CGPN", "Status", "MM Release Cause", "RR Release Cause"});

    resultsTable.setColumnCollapsingAllowed(true);
    resultsTable.setColumnCollapsed("mmRelCause", true);
    resultsTable.setColumnCollapsed("rrRelCause", true);

要基于 JQL 过滤数据,您可以执行filter传递过滤器字符串和绑定变量映射的方法。

...
whereParameters.put("stopTimeFrom", filterParams.getStopTimeFrom());                    
where = "e.startTime >= :stopTimeFrom";
...

container.filter(where, whereParameters);

如果你更喜欢 Criteria API,你可以使用criteriacontainer

于 2012-07-13T16:33:19.827 回答