有没有办法在没有JpaContainer的情况下使用vaadin和jpa?

时间:2012-07-05 07:35:10

标签: hibernate jpa vaadin

我正在尝试使用Vaadin和JPA Persistence层进行简单的概念验证。

我有一个与@OneToMany关系的Bean与fetchType = Lazy以及当我尝试使用我的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?

感谢。

3 个答案:

答案 0 :(得分:0)

您可以使用Bean(项目)容器并在那里添加您的实体。

如果您只是使用容器,则不会像使用JPAContainer那样延迟加载。

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

有关Bean(Item)容器和容器的更多信息here

答案 1 :(得分: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

答案 2 :(得分:0)

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

让我们看看你的用例:
- 您的浏览器请求您的申请 - 在您的服务器端代码中,您使用EntityManager加载bean(您的bean在会话中),但其关系实例(它是惰性的)是proxy =&gt;只有在您第一次访问关系实例时才会加载关系实例 - 您的浏览器收到回复
- 您单击一个按钮(例如),它向服务器发送请求
- 你试图添加/改变一些懒惰的关系 - 由于代理没有会话(它是使用上一个会话创建的,但现在它不再与会话相关联),它会引发异常

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

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

希望有所帮助