有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Hibernate JPA侦听器未收到调用

设置我有一个老项目,它坚持JDK1.5,因此spring和hibernate版本也是支持这个java版本的最大可能版本。Hibernate是3.3.2。GA和spring为3.1.1。释放安装程序如下所示:

<persistence-unit name="myUnit" transaction-type="RESOURCE_LOCAL">
    <mapping-file>persistence-query.xml</mapping-file>
    ...
    <properties>
        <property name="hibernate.max_fetch_depth" value="3" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <property name="hibernate.hbm2ddl.auto" value="validate" />
        <property name="hibernate.ejb.interceptor" value="com.myproj.common.dao.AuditInterceptor"/>         
    </properties>
</persistence-unit>

应用程序上下文:

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:jee="http://www.springframework.org/schema/jee"
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-3.0.xsd
     http://www.springframework.org/schema/tx
     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
     http://www.springframework.org/schema/aop
     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="..."/>                                         
<tx:annotation-driven transaction-manager="transactionManager" />   
<aop:aspectj-autoproxy/>   
<bean id="applicationContextProvder" class="com.myproj.common.utils.ApplicationContextProvider"/>   
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
 <property name="dataSource" ref="dataSource" />
</bean>

 <bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceXmlLocation" value="classpath:persistence.xml" />
    <property name="persistenceUnitName" value="myUnit" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter" />
    <property name="jpaDialect" ref="jpaDialect" />
 </bean>

<bean id="jpaVendorAdapter"
    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="database" value="ORACLE" />
    <property name="showSql" value="true" />
</bean>

<bean id="jpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />

<!-- Local transaction management -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
    <property name="dataSource" ref="dataSource" />
    <property name="jpaDialect" ref="jpaDialect" />
</bean> 

还有我的拦截器:

@Component
public class AuditInterceptor extends EmptyInterceptor {

private static final long serialVersionUID = 98658932451L;

@Autowired
private JdbcTemplate jdbcTemplate;

public void afterTransactionBegin(Transaction tx) {
    if (user != null) {
        jdbcTemplate.execute("call ah_audit_pkg.SetAudit('test')");
        super.afterTransactionBegin(tx);
     }
 }  
}

我运行一个junit来测试拦截器是否被调用。在调试模式下,我可以看到: enter image description here

感谢您的帮助!为什么我的intercetprot没有接到电话

编辑:

我还尝试了拦截器来覆盖后TransactionBegin,但没有帮助


共 (1) 个答案

  1. # 1 楼答案

    我最终得到了以下解决方案: 我的entityt是从超类映射实体扩展而来的:

    @Entity
    @Table(name = "my_table")
    public class MyTable extends AuditInfo
    

    AuditInfo实体具有以下映射:

    @MappedSuperclass
    public abstract class AuditInfo implements Serializable {
    
    ...
    
        @PrePersist
        void onCreate() throws SQLException {
            //this empty method is needed for AOP to trigger the audit information insert before entity is stored
        }
    
        @PreUpdate
        void onPersist() throws SQLException {
            //this empty method is needed for AOP to trigger the audit information insert before entity is updated
        }
    
        @PreRemove
        void onRemove() throws SQLException {
            //this empty method is needed for AOP to trigger the audit information insert before entity is removed
        }
    }
    

    以及Aspect类:

    @Aspect
    @Component
    public class MyAspect {
    
        @Before("execution(* com.mypackage.entities.AuditInfo.on*(..))")
        public void setAuditHistory(JoinPoint jp){      
            final AuditInfo info = ((AuditInfo)jp.getThis());
            JdbcTemplate jdbcTemplate = ApplicationContextProvider.getApplicationContext().getBean(JdbcTemplate.class);
            jdbcTemplate.execute(new CallableStatementCreator() {
                public CallableStatement createCallableStatement(Connection conn) throws SQLException {
                    CallableStatement stmt = conn.prepareCall("begin ah_audit_pkg.SetAudit(?,?); end;");
                    stmt.setString(1, info.getAuditUser());
                    if(info.getAuditLocation() != null && info.getAuditLocation().trim().length() !=0) {
                        stmt.setString(2, info.getAuditLocation());
                    } else {
                        stmt.setString(2, info.getAuditUser());
                    }
                    return stmt;
                }
            }, new CallableStatementCallback<Object>() {
                public Object doInCallableStatement(CallableStatement cs) throws SQLException, DataAccessException {
                    return cs.executeUpdate();
                }
            });
        }  
    }
    

    需要注意的是,SpringBean是从上下文中提取的,而不是自动连接的——这是因为AOP在Spring实现中是一个单例类,并且即使在上下文中可用,也不会实例化任何自动连接的Bean。因此,我必须手动检索它们,以供以后使用