java-ee – 如何使多个请求(使用Wicket和JPA)将实体(或其关联)附加到当前持久性上下文?

前端之家收集整理的这篇文章主要介绍了java-ee – 如何使多个请求(使用Wicket和JPA)将实体(或其关联)附加到当前持久性上下文?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用 Java EE上的基于Wicket的Web应用程序.

我试图找到一种方法来确保用作模型对象的任何实体始终附加到当前的EntityManager之前,Wicket会尝试渲染任何组件.这样,当组件从其模型中抓取数据时,数据可以根据需要被实体轻松加载.

有很多教程,在这里的一些帖子,引用LoadableDetachableModels(LDM)作为解决方案.当我们不需要在中间请求之间保持任何状态时,这对我们有用.在这种情况下,无论何时呈现页面,LDM将从数据库中加载所需实体的最新版本.

然而,有时用户需要在保存数据之前通过多个步骤以有状态编辑数据,因此模型需要将实体保留在“未保存”状态. LDM将在每个步骤上有效地消除用户的更改.

到目前为止,我们一直在使用一个将实体与持久化上下文合并的模型.这是一个简化版本:

public final class DetachableMergingModel<E extends Identifiable> implements IModel<E> {

    private E entity;
    private boolean attached = false;

    public DetachableMergingModel(E entity) {
        this.entity = entity;
    }

    @Override
    public E getObject() {
        if (!attached) {
            attached = true;
            // Non-transactional method merges entity with persistence context 
            // but does not flush any data to database
            entity = getRepository().merge(entity);
            }
        }
        return entity;
    }

    @Override
    public void setObject(E entity) {
        this.entity = entity;
    }

    @Override
    public void detach() {
        // This ensures that the next call to getObject() will merge the entity with 
        // the persistence context
        attached = false;
    }
    /* ... */
}

我们的EntityManager由GlassFish注入,它跨越了一个完整的servlet请求,所以当实体被附加到持久性上下文时,它将保持附加,直到页面被渲染为止.

上面的模型处理实体已经被持久化并正在被编辑的情况.每当页面上的一个组件在此模型上调用getObject()时,Model将会将实体与持久性上下文合并,并且我们可以自由导航实体的整个对象图,而不会抛出任何LazyInitializationExceptions.

但是,在实体是新的且尚未被持久化的情况下,我们不能使用此模型,因为实体尚未准备好合并.当用户正在创建一个新实体时,通常会出现这种情况,并且仍然需要通过表单将其填充.在这种情况下,我们希望拥有相同的自由度导航实体的对象图(因为一些关联已经被设置,比如实体的父),而不用担心LazyInitializationException.

类似的解决方案描述为here(选项#3),但不包括上述“新实体”用例.

有没有人遇到这种用例?你是怎么解决的?有没有更好的方式整合Wicket与JPA比通过自定义IModel实现?

解决方法

我这样的情况,我通常创建一个DTO保留我需要创建一个实体的所有数据.
如果您需要引用现有实体 – 将它们作为单独的模型传递给您的表单/面板.提交表格时,您可以:

>执行验证
>从编辑的DTO创建一个新实体
>注入对存储在这些单独LDM模型中的其他实体的引用.
>坚持实体.

这有点麻烦,但确实有效.

跨越多个请求的对话在纯门户网站中不可用,可能永远不会 – 这不是检票口的区域.

Seam支持长时间的对话,它支持小门(我从来没有使用过缝 – 我不能在这个上建议你).

猜你在找的Java相关文章