2012-10-18 4 views
6

Stavo usando listener di eventi Hibernate come PostDeleteEventListener, PostInsertEventListener, PostUpdateEventListener per eseguire alcune operazioni durante l'inserimento, l'eliminazione e l'aggiornamento. Ora vorrei usare il listener JPA per farlo perché se mi piace passare da Hibernate a qualsiasi altro provider JPA il mio ascoltatore dovrebbe funzionare. L'ascoltatore di ibernazione mi dà event da cui posso ottenere la transazione e controllare se è stato eseguito il commit o il rollback. Gli ascoltatori JPA mi forniscono solo l'oggetto entità. Ora, come posso ottenere la transazione o la sessione o il gestore di entità nel listener JPA ?? Grazie in anticipo!! Sto usando Jboss come mio CMT.Come ottenere gestore entità o transazione in jpa listener

risposta

6

Questo non è supportato come di JPA 2.0.

In JPA 2.1 (previsto per essere in Java EE 7), il provider di persistenza considererà i listener di entità come bean CDI quando si trovano in un ambiente gestito (ad esempio l'app server JBoss). Dalla Proposed Final Draft of the JPA 2.1 spec, pagina 96:

entità classi ascoltatore in Java EE ambienti di supporto dipendenza iniezione attraverso l'API Contesti e Dependency Injection (CDI) [10] quando l'archivio contenente è un archivio di fagioli. Una classe listener dell'entità che fa uso dell'iniezione CDI può anche definire i metodi di callback del ciclo di vita annotati con le annotazioni PostConstruct e PreDestroy . Questi metodi saranno invocati dopo l'iniezione ha preso luogo e prima che l'istanza dell'entità ascoltatore viene distrutta rispettivamente

Quindi, in JPA 2.1, se si crea un produttore CDI che fornisce EntityManager (semplicemente annotando un campo @PersistenceContext con @ Produce), puoi semplicemente @Introdurre EntityManager nell'ascoltatore.

Nel frattempo, non sono a conoscenza di alcuna soluzione pulita o piacevole. La cosa "meno peggio" che posso pensare sarebbe configurare EntityManager per essere associato in JNDI, quindi ottenerlo attraverso una ricerca JNDI dall'interno del listener.

-1

È possibile utilizzare tutti i pre/carico postale, inserire, aggiornare o cancellare ascoltatore in JPA utilizzando due modi:

  1. Utilizzando annotazione. Un semplice esempio di utilizzo di un ascoltatore potrebbe essere se un'entità ha una variabile transitoria che deve essere popolato dopo che l'entità ha persistito, aggiornati o caricato, come:

    public class AvailableCreditListener { 
        @PostLoad 
        @PostPersist 
        @PostUpdate 
        public void calculateAvailableCredit(Account account) { 
         account.setAvailableCredit(
          account.getBalance().add(
          account.getOverdraftLimit())); 
        } 
    } 
    

    La classe entità sarebbe annotato con @ EntityListeners:

    @EntityListeners({AvailableCreditListener.class}) 
    public class Account extends BaseEntity { 
        private BigDecimal balance; 
        private BigDecimal overdraftLimit; 
        @Transient 
        private BigDecimal availableCredit; 
        // getters and setters 
    } 
    
  2. utilizzando file di configurazione persistence.xml.

Infine, invece di annotazioni, di un file di mapping XML può essere utilizzato e distribuito con l'applicazione per specificare gli ascoltatori di default. (Questo file di mapping fa riferimento al file persistence.xml). Tuttavia, un'entità può utilizzare l'annotazione @ExcludeDefaultListeners se non desidera utilizzare i listener predefiniti.

@ExcludeDefaultListeners 
@Entity 
public class Account extends BaseEntity { 
    .... 
} 

Nel vostro persistence.xml:

<persistence-unit-metadata> 
    <persistence-unit-defaults> 
     <entity-listeners> 
     <entity-listener class="samples.AvailableCreditListener"/>  
     </entity-listeners> 
    </persistence-unit-defaults> 
    </persistence-unit-metadata> 
+6

La mia domanda è come ottenere l'entityManager nella classe AvailableCreditListener – Muzy

1

Nel mio caso sto usando questo codice:

ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext(); 
auditLogService = (AuditLogService) ctx.getBean("auditLogService"); 

Questo metodo funziona bene per me.

Il codice di questa applicazione è disponibile per il download presso https://bitbucket.org/macielbombonato/apolo

Spero che questo ti può aiutare.

+0

questa dovrebbe essere indicata come "una risposta", ma la risposta esplicita (nel caso generale) sarebbe, ottenere l'entityManager tramite la ricerca JNDI, ma il binding specifico per l'uso sarebbe specifico del contenitore (JBoss, Glassfish, Weblogic, ecc.) – him