当前位置: 首页 > 面试题库 >

在Hibernate的EmptyInterceptor中注入JPA的实体管理器

宦正诚
2023-03-14
问题内容

我在数据访问层中将JPA-2.0与Hibernate一起使用。

为了进行审核日志记录,我通过在persistence.xml中配置以下属性来使用Hibernate的EmptyInterceptor:

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

AuditLogInterceptor 扩展Hibernate的’ org.hibernate.EmptyInterceptor ‘。

public class AuditLogInterceptor extends EmptyInterceptor {

    private Long userId;

    public AuditLogInterceptor() {}

    @Override  
    public boolean onSave(Object entity, Serializable id, Object[] state,  
            String[] propertyNames, Type[] types) throws CallbackException {  
        // Need to perform database operations using JPA entity manager
        return false;  
    }

   @Override
    public boolean onFlushDirty(Object entity, Serializable id,
            Object[] currentState, Object[] previousState,
            String[] propertyNames, Type[] types) {
        // other code here        
        return false;
    }

    @Override  
    public void postFlush(Iterator iterator) throws CallbackException {  
        System.out.println("I am on postFlush");
        // other code here 
    }  
}

我在数据访问层中使用JPA实体管理器来执行数据库操作。JPA配置如下所示:

<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>

我的AbstractDAO是:

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);       
    }

}

我想在“ AuditLogInterceptor”中注入JPA实体管理器,以便可以像我的抽象DAO在“
AuditLogInterceptor”中执行数据库操作。

任何的想法?什么是正确的解决方案?


问题答案:

我有一个简单的方法可以在“ AuditLogInterceptor”中使用JPA实体管理器执行数据库操作

我创建了下面的类,该类将提供应用程序上下文参考:

@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;
        }
    }

创建的数据访问类:

@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);
    }
}

并在“ AuditLogInterceptor”中使用“ ApplicationContextProvider”来获取“
MyAuditDAO”的引用,该引用具有JPA实体管理器作为在DAO初始化期间注入的属性。现在,借助“ MyAuditDAO”,我可以执行数据库操作。

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);

    }  
}


 类似资料:
  • 目前,我学习JavaEE JPA规范。我使用Hibernate作为JPA实现。我有下一个问题: 我有一个简单的实体 还有一个简单的服务: persistence.xml有下一个视图: 我不明白为什么Hibernate会话没有注入BookService。在作为EntityManager的图书服务中,我得到了org.jboss.as.TransactionScopedEntityManager而不是来

  • 问题内容: 专家/大师/朋友 我们正在使用Spring 3.2,JPA 2,Hibernate 4.2组合,并在尝试将任何带弹簧注释的bean注入实现的EmtyInterceptor时,遇到了这个奇怪的null指针问题,如下所示。我们已经尝试给这个豆子和一个春天豆子添加注释,但是没有运气。 非常感谢您为解决这个难题提供的任何帮助。 在应用程序的其他任何地方,注入都像没有任何问题的魅力一样。这是我们

  • 专家/大师/朋友 我们正在使用Spring 3.2、JPA 2、Hibernate 4.2组合,并面临这个奇怪的空指针问题,同时试图将任何Spring注释的bean注入到EmtyInterceptor中,实现如下所示。我们试着给这个豆子和Spring的豆子注释,但是没有成功。 非常感谢您对解决这个难题的任何帮助。 在应用程序的其他地方,注入就像一个魅力,没有任何问题。这是我们的应用程序上下文。xm

  • 和 只是使用不同的jndi名称(即CHServiceBean com.....)的javax.persistence.EntityManager类型的java:comp/env/chjpa引用,等等)得到了相同的错误。 最后,根据这篇文章:访问EntityManager时的错误-openjpa-自由配置文件似乎是我不能拥有完整的JavaEE7特性并运行JPA2.0吗?请指教!

  • 我有一个EAR应用程序(要部署在WebLogic12c上),它有一个“持久化”组件。“persist”组件使用JPA(实现:EclipseLink)来持久化对象。 使用entityManager的bean声明为,实体管理器通过注释注入。 问题是,我每次尝试访问entityManager时都有一个(意思是他没有被正确注入)。 persistence.xml 我在常规代码中是这样使用的: MyBean

  • 我试图使用spring boot将EntityManager注释注入到我的DAO中,但是得到一个< code > InvalidDataAccessApiUsageException 消息,说没有可用的事务EntityManager。我的印象是,只要Spring Boot从< code>application.yml中获得了我的数据源信息,并且我用< code>@PersitenceContext