2012-02-03 5 views
5

Tengo una aplicación Sandbox Seam 3 con JBoss 7, Hibernate como implementación JPA predeterminada y JSF como interfaz web.JPA/Hibernate no emite ninguna ACTUALIZACIÓN en la confirmación en el entorno EJB/Seam

Tengo el problema de que la ACTUALIZACIÓN de SQL está anulada por defecto.

Mi EJB con estado en el ámbito de conversación mantiene una prolongada con ámbito EntityManager y una entidad, contenedores Transacciones gestionados (Requiere nueva)

  1. El EntityManager se inyecta
  2. El EJB utiliza el EM para cargar la Entidad y mantiene en un campo
  3. aplicación JSF tiene acceso a la EJB y su entidad, cambia un campo cadena método
  4. calles de aplicaciones JSF "Guardar" en EJB
  5. en save() Yo verifico, si el campo Entities fue cambiado -> fue cambiado correctamente
  6. No hago nada más, el contenedor confirma la transacción luego de que save() haya terminado.
  7. Problema: No se realiza ninguna actualización de SQL en la base de datos.

Si extiendo guardar() por:

a) entityManager.contains (entidad) Se ejecuta la actualización como se esperaba (resultado es "verdadero")

O

b) entityManager.persist (entidad) la ACTUALIZACIÓN se ejecuta como se esperaba

P: Por lo que yo entiendo, las especificaciones ni de a) ob) deben ser requeridas, porque la entidad permanece administrada durante todo el proceso. No entiendo, por qué a) tiene un efecto en el ahorro. Puedo obtener imágenes del b) tiene un efecto en el ahorro, pero no debería ser necesario, ¿o sí?

Cualquier explicación es bienvenida.

Aquí es mi EJB:

@Named 
@ConversationScoped 
@Stateful 
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
public class LanguageBean { 

    @PersistenceContext(type = PersistenceContextType.EXTENDED) 
    private EntityManager em; 
    @Inject 
    private UserTransaction transaction; 

    private Language value; 

    @Inject 
    Conversation conversation; 

    public LanguageBean() { 
     super(); 
    } 

    @Begin 
    public void selectLanguage(Long anId) { 
     conversation.setTimeout(10 * 60 * 1000); 
     if (anId != null) { 
      value = em.find(Language.class, anId); 
     } 
    } 

    @BeforeCompletion 
    public void transactionComplete(){ 
     System.out.println("transactionComplete"); 
    } 

    public Language getValue() { 
     return value; 
    } 

    @Produces 
    @Named 
    @ConversationScoped 
    public Language getLanguage() { 
     return getValue(); 
    } 

    public void setValue(Language aValue) { 
     value = aValue; 
    } 

    @End 
    public String save() { 
//  displays the changed attribute: 
     System.out.println("save code: "+value.getCode()); 

//  why is either this required: 
//  boolean tempContains = em.contains(value); 
//  System.out.println("managed: "+tempContains); 

//  or: why is persist required: 
     em.persist(value); 
     return "languages?faces-redirect=true"; 
    } 

    @End 
    public String cancel() throws SystemException { 
     transaction.setRollbackOnly(); 
     return "languages?faces-redirect=true"; 
    } 

} 
+0

que descubrí EntityManager.flush() también resuelve el problema. Pero no entiendo por qué parece ser necesario. De la especificación JPA: "Cuando la transacción JTA se compromete, el proveedor debe eliminar todos los estados de la entidad modificada a la base de datos ". – user1187037

+0

¿quizás en alguna parte el FlushMode de la sesión de hibernación está configurado en none? – Firo

Respuesta

0

intenta agregar @Remove anotación en métodos anotados por @End.

En mi opinión @End anotación no resulta en la destrucción de frijol. Entonces, el contexto de persistencia está activo incluso después de la ejecución de save() y su contenido no se puede descargar a la base de datos.

1

Mi experiencia es en gran medida con seam-2 pero debería ser igualmente aplicable aquí.

La sesión de conversación y JPA está desacoplada en la costura por el simple motivo de que una conversación que termina no puede dar como resultado que la entidad se guarde.

Por ejemplo, una acción de cancelación de una conversación de larga ejecución pondría fin a la conversación (ya que no hay ninguna razón para mantener la conversación más)

Teniendo en cuenta que usted está haciendo una reversión en la cancelación de su ejemplo, también parece lógico que necesite llamar a un color según lo sugerido por @ user1187037 (teóricamente una confirmación, pero no creo que esté permitido)

Creo que podría haber una configuración que podría establecerse para que funcionara al final de la conversación, pero puedo estar equivocado.

En cualquier caso, http://javalangblog.blogspot.co.uk/2010/04/flush-mode-conversation.html parece sugerir una solución

Espero que ayude.

EDIT: Puede configurar el modo de descarga por conversación usando XML

<begin-conversation join="true" flush-mode="COMMIT" /> 

y anotaciones

@Begin(flushMode=COMMIT) 

usando Tenga en cuenta sin embargo que una conversación puede @end sin que se define de forma explícita. Si un usuario está en medio de la conversación, realizó cambios en las entidades y luego abandona la conversación, se cerrará automáticamente después de un tiempo de espera. Si recuerdo correctamente, esto hará que se cometan cambios en el caso anterior.

Referencias:

http://docs.jboss.org/seam/3/persistence/3.0.0.Alpha1/reference/en-US/html_single/#d0e249 http://docs.jboss.org/seam/3/latest/api/org/jboss/seam/persistence/FlushModeType.html

Cuestiones relacionadas