2013-10-07 4 views
6

Ich verwende JPA-2.0 mit Hibernate in meiner Datenzugriffsschicht.Den Entity Manager von JPA in den EmptyInterceptor von Hibernate einfügen

Für Audit-Protokollierung, ich bin mit EmptyInterceptor des Hibernate von unten Eigenschaft in persistence.xml konfigurieren:

<property name="hibernate.ejb.interceptor" 
       value="com.mycom.audit.AuditLogInterceptor" /> 

Wo AuditLogInterceptor erstreckt Hibernate 'org.hibernate.EmptyInterceptor'.

Ich verwende JPA-Entity-Manager in Datenzugriffsebene, um Datenbankvorgänge durchzuführen. JPA-Konfiguration ist wie folgt:

<bean id="entityManagerFactory" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
     p:persistenceUnitName="PersistenceUnit" 
     p:persistenceXmlLocation="classpath*:persistence.xml" 
     p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter"> 
     <property name="loadTimeWeaver"> 
      <bean 
       class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /> 
     </property> 
    </bean> 

Mein AbstractDAO ist:

public class AbstractDao<T, ID extends Serializable> { 

    private final transient Class<T> persistentClass; 

    protected transient EntityManager entityManager; 

    @SuppressWarnings("unchecked") 
    public AbstractDao() { 

     this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 
    } 

    @PersistenceContext 
    public final void setEntityManager(final EntityManager entityMgrToSet) { 

     this.entityManager = entityMgrToSet; 
    } 

    public final Class<T> getPersistentClass() { 

     return persistentClass; 
    } 

    public final void persist(final T entity) { 

     entityManager.persist(entity);  
    } 

} 

Ich möchte JPA Entity-Manager in 'AuditLogInterceptor' injizieren, so dass ich Datenbankoperationen in 'AuditLogInterceptor' durchführen kann, wie mein abstrakte DAO.

Irgendeine Idee? Was sollte die richtige Lösung sein?

Antwort

7

Ich habe eine einfache Art und Weise bekam Datenbankoperation mit JPA Entity-Manager in ‚AuditLogInterceptor‘

ich unter Klasse erstellt haben, durchzuführen, die den Anwendungskontext Bezug zu geben:

@Component("applicationContextProvider") 
    public class ApplicationContextProvider implements ApplicationContextAware { 
     private static ApplicationContext context; 

     public static ApplicationContext getApplicationContext() { 
      return context; 
     } 

     @Override 
     public void setApplicationContext(ApplicationContext ctx) { 
      context = ctx; 
     } 
    } 

erstellten Datenzugriffsklasse :

@Repository("myAuditDAO") 
public class myAuditDAO<T, ID extends Serializable> { 

    private final transient Class<T> persistentClass; 

    protected transient EntityManager entityManager; 

    @SuppressWarnings("unchecked") 
    public MyDAO() { 

     this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; 
    } 

    @PersistenceContext 
    public final void setEntityManager(final EntityManager entityMgrToSet) { 

     this.entityManager = entityMgrToSet; 
    } 

    public final Class<T> getPersistentClass() { 

     return persistentClass; 
    } 

    public final T findById(final ID theId) { 

     return entityManager.find(persistentClass, theId); 
    } 

    public final void persist(final T entity) { 

     entityManager.persist(entity); 
    } 

    public final void merge(final T entity) { 

     entityManager.merge(entity); 
    } 
} 

Und 'ApplicationContextProvider' in 'AuditLogInterceptor' verwendet, um die Referenz von 'MyAuditDAO' zu erhalten, die JPA enti ist mit Manager als eine Eigenschaft, die während der DAO-Initialisierung injiziert wird. Jetzt kann ich mit Hilfe von 'MyAuditDAO' Datenbankoperationen durchführen.

public class AuditLogInterceptor extends EmptyInterceptor { 

    @Override 
    public void postFlush(Iterator iterator) throws CallbackException { 

     // Here we can get the MyAuditDao reference and can perform persiste/merge options 
     MyAuditDao myAuditDao = (MyAuditDao) ApplicationContextProvider.getApplicationContext().getBean("myAuditDao"); 

     // myAuditDao.persist(myEntity); 

    } 
} 
+0

Was ist mit Gewindesicherheit? –

+0

Ich versuche es in JPA2 zu tun, um einen Verweis auf mein auditLogRepository zu erhalten, da die @Resource-Annotation nichts injiziert hat und mir eine NPE hinterlassen hat. – Stephane

0

Ich erwäge persistenceManager initiiert erfolgreich in Ihrer abstrakten Klasse. Sie können eine Klasse AuditLogDAO haben, die Ihre AbstractDao erweitert. Injizieren Sie die AuditLogDAO-Klasse in Ihren Interceptor und rufen Sie auditLogDAO.save(entity); und andere Methoden auf.

Oder schreiben Sie eine Util Klasse, die DB-Operationen durchführt und die Util-Klasse zu Ihrem Interceptor injiziert.

Verwandte Themen