2011-08-15 12 views
11

Estoy trabajando en una aplicación web basada en Wicket en Java EE.¿Cómo mantengo las entidades (o sus asociaciones) unidas al contexto de persistencia actual en varias solicitudes (usando Wicket y JPA)?

Estoy tratando de encontrar la forma de garantizar que las entidades utilizadas como objetos de modelo siempre se adjunten al EntityManager actual antes de que Wicket intente representar los componentes. De esta forma, cuando los componentes toman datos de su modelo, la entidad puede cargar los datos de forma perezosa según sea necesario.

Hay muchos tutoriales y algunas publicaciones aquí, que se refieren a los modelos cargables de baja densidad (LDL) como la solución. Esto nos ha funcionado cuando no necesitamos mantener ningún estado entre las solicitudes. En estos casos, siempre que se represente la página, el LDM cargará la versión más reciente de la entidad requerida de la base de datos.

Sin embargo, hay ocasiones en que un usuario necesita editar datos en forma de estado a través de varios pasos antes de guardar los datos, por lo que el modelo necesita retener la entidad en su estado "no guardado". Un LDM eliminaría efectivamente los cambios del usuario en cada paso.

Hasta ahora, hemos estado utilizando un modelo que combina la entidad con el contexto de persistencia cuando sea necesario. He aquí una versión simplificada:

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; 
    } 
    /* ... */ 
} 

Nuestra EntityManager es inyectado por GlassFish y se extiende por una petición de servlet conjunto, por lo que cuando una entidad está unida al contexto de persistencia, permanecerá conectado hasta que la página ha sido prestado.

Este modelo anterior se ocupa de situaciones en las que la entidad ya se ha conservado y se está editando. Cada vez que un componente en la página llama a getObject() en este modelo, el modelo fusionará la entidad con el contexto de persistencia, y podemos navegar libremente por el gráfico de objeto entero de la entidad sin lanzar ninguna LazyInitializationExceptions.

Sin embargo, en una situación en la que la entidad es nueva y no se ha conservado, no podemos usar este Modelo porque la entidad aún no está lista para fusionarse. Este es a menudo el caso cuando el usuario está creando una nueva entidad, y aún necesita llenarla con valores a través del formulario. En este caso, queremos tener la misma libertad navegando en el gráfico de objeto de la entidad (ya que algunas asociaciones ya se han establecido, como el padre de la entidad), sin temor a una LazyInitializationException.

Se describe una solución similar here (opción # 3), pero no cubre el caso de uso de 'nueva entidad' descrito anteriormente.

¿Alguien ha encontrado este caso de uso? ¿Cómo lo resolvió? ¿Existe una mejor manera de integrar Wicket con JPA que a través de implementaciones de IModel personalizados?

+0

Es posible que desee ver el código de Databinder. Es una capa delgada entre Wicket e Hibernate, que utiliza un modelo de carga descargable para acceder a los objetos de hibernación a través de ID o SQL (o Criteria, etc.). Sin embargo, también permite mantener una referencia a objetos no permanentes a través de varias solicitudes. Al persistir el objeto, deja caer la referencia y vuelve a la versión cargable/desmontable, etc. – jbrookover

Respuesta

1

En casos como este, generalmente creo un DTO manteniendo todos los datos que necesito para crear una entidad. Si necesita hacer referencia a entidades existentes, páselos a sus formularios/paneles como modelos independientes. Cuando se envía el formulario a continuación, puede:

  • realizar la validación
  • crear una nueva entidad de DTO que fue editado
  • inyectar referencias a otras entidades que haya almacenado en esos modelos LDM separadas.
  • persistir la entidad.

Es un poco molesto pero realmente funciona.

Las conversaciones que abarcan varias solicitudes no están disponibles en wicket puro y probablemente nunca lo estarán; esta no es área de wicket.

Seam admite largas conversaciones y admite wicket (nunca he usado costuras; no puedo aconsejarle sobre esta).

0

parece ser un antiguo puesto tipode ..

espero que ayudará a algunos otros modos:

Primero: Su LDM es un poco inútil, porque la propiedad entidad no es transitoria. Por lo tanto, su entidad se serializa en su tienda de sesiones y ese no es el significado de un LDM. Se supone que minimiza el tamaño de serialización de cualquier modelo de datos.

Segundo: Su problema no es un problema real, Porque lo que usted necesita, es lo que ya tiene: desea preparar una Entidad en varias páginas para ser finalmente almacenado en su base de datos (un mago o menos. .). Ahora que su LDM está completamente serializado en su tienda de sesiones entre las solicitudes del cliente, su entidad y sus datos editados sobreviven a múltiples solicitudes, sin necesidad de ninguna fusión. Tan pronto como tu asistente termine, simplemente persistes la entidad del agujero. Antes de que la entidad se encuentre en su estado final, no tiene sentido insistir en nada (aunque sobrevive a las solicitudes en su tienda de sesiones).

Ni siquiera necesita el LDM para este tipo de funcionalidad ..

se limitan a dar la entidad como parámetro a la siguiente página, donde el usuario puede completar sus datos.

Espero que haya resuelto este problema ya ..

Cuestiones relacionadas