hibernate.ejb.interceptor 不“拦截”,Spring+JPA

发布于 2024-11-04 13:57:34 字数 6958 浏览 3 评论 0原文

各位 - 我正在尝试设置 hibernate.ejb.interceptor 但由于某种原因它永远无法“拦截”任何更新或插入事件。该应用程序似乎工作正常,更新和插入实体但没有拦截。

我找不到我的设置有什么问题,请帮助:

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

    <persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <non-jta-data-source>jdbc/myDS</non-jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />

            <property name="hibernate.ejb.interceptor"
                value="my.AuditLogInterceptor" />

        </properties>
    </persistence-unit>
</persistence>  

Application-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>

    <mvc:resources mapping="/resources/**" location="/resources/" />

    <mvc:annotation-driven />

    <context:component-scan base-package="my.package" />

    <tx:annotation-driven />

    <context:annotation-config
        transaction-manager="transactionManager" proxy-target-class="false" />

    <jee:jndi-lookup id="myDS" jndi-name="jdbc/myDS"
        resource-ref="true" />

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass">
            <value>
                org.springframework.web.servlet.view.tiles2.TilesView
        </value>
        </property>
    </bean>

    <bean id="tilesConfigurer"
        class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles/tiles.xml</value>
            </list>
        </property>
    </bean>


    <bean id="myEMF"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="myDS" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="myEMF" />
        <property name="dataSource" ref="myDS" />
    </bean>

    <bean id="jpaVendorAdapter"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    </bean>

    <bean id="validator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

    <bean id="auditLog" class="my.AuditLog" />

    <bean
        class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>

拦截器(来自曼宁书):

public class AuditLogInterceptor extends EmptyInterceptor {
    /**
     * 
     */
    private static final long serialVersionUID = -634733855120326803L;

    /**
     * 
     */
    private XLogger logger = XLoggerFactory
            .getXLogger(AuditLogInterceptor.class.getName());

    private Session session;
    private Long userId;
    private Set<Auditable> inserts = new HashSet<Auditable>();
    private Set<Auditable> updates = new HashSet<Auditable>();

    public AuditLogInterceptor() {}

    public void setSession(Session session) {
        this.session = session;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state,
            String[] propertyNames, Type[] types) throws CallbackException {
        logger.entry(entity, id, state, propertyNames);

        if (entity instanceof Auditable)
            inserts.add((Auditable) entity);

        logger.exit();

        return false;
    }

    @Override
    public boolean onFlushDirty(Object entity, Serializable id,
            Object[] currentState, Object[] previousState,
            String[] propertyNames, Type[] types) throws CallbackException {
        logger.entry(entity, id, currentState, previousState);

        if (entity instanceof Auditable)
            updates.add((Auditable) entity);

        logger.exit();

        return false;
    }

    @Override
    public void postFlush(Iterator iterator) throws CallbackException {
        logger.entry(iterator);

        try {
            for (Auditable entity : inserts) {
                AuditLog.logEvent("create", entity, "userId");
            }           

            for (Auditable entity : inserts) {
                new AuditLog().logEvent("update", entity, "userId");
            }

        } finally {
            inserts.clear();
            updates.clear();
        }

        logger.exit();
    }
}

Spring bean(在网上找到的):

public class AuditLog {

    static protected AuditLog theAuditLog = null;

    @PersistenceContext(unitName = "myPU")
    protected EntityManager itsEntityManager;

    public AuditLog() {
        theAuditLog = this;
    }

    /**
     * 
     * @return the entity manager
     */
    protected EntityManager getEntityManager() {
        return this.itsEntityManager;
    }

    /**
     * 
     * @return Hibernate Session
     */
    protected Session getHibernateSession() {
        return (Session) getEntityManager().getDelegate();
    }

    public static void logEvent(String action, Auditable entity, String userId) {
        /*
         * TODO get rid of this .connection() - deprecated - call !
         */
        Session tempSession = theAuditLog.getHibernateSession()
                .getSessionFactory()
                .openSession(theAuditLog.getHibernateSession().connection());

        try {
            AuditLogRecord alr = new AuditLogRecord();
            alr.entityId = entity.getId();
            alr.entityClass = entity.getClass();
            alr.message = "Something changed";
            alr.created = new Date();

            tempSession.save(alr);
            tempSession.flush();
        } catch (Exception ex) {
            throw new CallbackException(ex);
        } finally {
            try {
                tempSession.close();
            } catch (HibernateException ex) {
                throw new CallbackException(ex);
            }
        }
    }
}

Folks- I am trying to set up hibernate.ejb.interceptor but for some reason it never gets to 'intercept' any update or insert event. The application seems to work fine, updating and inserting entities but no interception.

I cannot find what is wrong with my setup, please help:

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

    <persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <non-jta-data-source>jdbc/myDS</non-jta-data-source>
        <properties>
            <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServerDialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="update" />

            <property name="hibernate.ejb.interceptor"
                value="my.AuditLogInterceptor" />

        </properties>
    </persistence-unit>
</persistence>  

Application-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>

    <mvc:resources mapping="/resources/**" location="/resources/" />

    <mvc:annotation-driven />

    <context:component-scan base-package="my.package" />

    <tx:annotation-driven />

    <context:annotation-config
        transaction-manager="transactionManager" proxy-target-class="false" />

    <jee:jndi-lookup id="myDS" jndi-name="jdbc/myDS"
        resource-ref="true" />

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass">
            <value>
                org.springframework.web.servlet.view.tiles2.TilesView
        </value>
        </property>
    </bean>

    <bean id="tilesConfigurer"
        class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles/tiles.xml</value>
            </list>
        </property>
    </bean>


    <bean id="myEMF"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="myDS" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="myEMF" />
        <property name="dataSource" ref="myDS" />
    </bean>

    <bean id="jpaVendorAdapter"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    </bean>

    <bean id="validator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

    <bean id="auditLog" class="my.AuditLog" />

    <bean
        class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>

Interceptor (From manning book):

public class AuditLogInterceptor extends EmptyInterceptor {
    /**
     * 
     */
    private static final long serialVersionUID = -634733855120326803L;

    /**
     * 
     */
    private XLogger logger = XLoggerFactory
            .getXLogger(AuditLogInterceptor.class.getName());

    private Session session;
    private Long userId;
    private Set<Auditable> inserts = new HashSet<Auditable>();
    private Set<Auditable> updates = new HashSet<Auditable>();

    public AuditLogInterceptor() {}

    public void setSession(Session session) {
        this.session = session;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    @Override
    public boolean onSave(Object entity, Serializable id, Object[] state,
            String[] propertyNames, Type[] types) throws CallbackException {
        logger.entry(entity, id, state, propertyNames);

        if (entity instanceof Auditable)
            inserts.add((Auditable) entity);

        logger.exit();

        return false;
    }

    @Override
    public boolean onFlushDirty(Object entity, Serializable id,
            Object[] currentState, Object[] previousState,
            String[] propertyNames, Type[] types) throws CallbackException {
        logger.entry(entity, id, currentState, previousState);

        if (entity instanceof Auditable)
            updates.add((Auditable) entity);

        logger.exit();

        return false;
    }

    @Override
    public void postFlush(Iterator iterator) throws CallbackException {
        logger.entry(iterator);

        try {
            for (Auditable entity : inserts) {
                AuditLog.logEvent("create", entity, "userId");
            }           

            for (Auditable entity : inserts) {
                new AuditLog().logEvent("update", entity, "userId");
            }

        } finally {
            inserts.clear();
            updates.clear();
        }

        logger.exit();
    }
}

The Spring bean (found it on the web):

public class AuditLog {

    static protected AuditLog theAuditLog = null;

    @PersistenceContext(unitName = "myPU")
    protected EntityManager itsEntityManager;

    public AuditLog() {
        theAuditLog = this;
    }

    /**
     * 
     * @return the entity manager
     */
    protected EntityManager getEntityManager() {
        return this.itsEntityManager;
    }

    /**
     * 
     * @return Hibernate Session
     */
    protected Session getHibernateSession() {
        return (Session) getEntityManager().getDelegate();
    }

    public static void logEvent(String action, Auditable entity, String userId) {
        /*
         * TODO get rid of this .connection() - deprecated - call !
         */
        Session tempSession = theAuditLog.getHibernateSession()
                .getSessionFactory()
                .openSession(theAuditLog.getHibernateSession().connection());

        try {
            AuditLogRecord alr = new AuditLogRecord();
            alr.entityId = entity.getId();
            alr.entityClass = entity.getClass();
            alr.message = "Something changed";
            alr.created = new Date();

            tempSession.save(alr);
            tempSession.flush();
        } catch (Exception ex) {
            throw new CallbackException(ex);
        } finally {
            try {
                tempSession.close();
            } catch (HibernateException ex) {
                throw new CallbackException(ex);
            }
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文