切入点中的JPA entityManager为null

时间:2011-03-20 23:22:52

标签: jpa aop aspectj entitymanager

我在班上使用@Aspect注释定义了一个切入点。

我使用我在上下文中定义的自定义注释来配置切入点:

<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- Messaging pointcut -->
<bean id="messagePointcut" class="com.adobe.codex.aspects.MessagePointcut" >
    <constructor-arg ref="msgPointcutEntityFactory"/>   
    <property name="buildDao" ref="buildDao"/>  
</bean>


<!-- enable our own annotation  -->
<aop:config proxy-target-class="true">
    <aop:aspect ref="messagePointcut">
        <aop:pointcut id="proxiedMethods" expression="@annotation(com..codex.aspects.annotation.MessageGateway)"/>
        <aop:around pointcut-ref="proxiedMethods" method="interceptAnnotatedMethod"/>
    </aop:aspect>
</aop:config>

不幸的是,如果我在切入点中引用了buildDao,buildDao中的entityManager总是为null。

不确定解决此问题的最佳方法是什么。

我假设问题是所使用的编织(加载时间)不知道如何从entityManagerFactory bean创建一个entityManager。

这是我的dao上下文的片段。

<context:annotation-config /> 
<bean id="entityManagerFactory"
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="jpaProperties">
        <util:properties
            location="classpath:com//codex/dao/jpa/hibernate.properties" />
    </property>
</bean>

<bean id="buildDao" class="com..codex.dao.jpa.JpaBuildDao">
    <description>
        A DAO for Builds.
    </description>
    <property name="queryHelper" ref="queryHelper" />  
    <property name="partDao" ref="partDao" />   
    <property name="buildQueryFactory" ref="buildQueryFactory" />   

</bean>    

这是我的切入点:

@Aspect @Transactional() 公共类MessagePointcut实现Ordered,MsgObservable {

private   MsgPointcutEntityFactory msgEntityFactory;
private   BuildDao buildDao;


public void setBuildDao(BuildDao buildDao) {
    this.buildDao = buildDao;
}



public MessagePointcut(MsgPointcutEntityFactory msgEntityFactory){
    this.msgEntityFactory = msgEntityFactory;
}

@Transactional(readOnly = true)
public Object interceptAnnotatedMethod(ProceedingJoinPoint pjp) {
    Object returnedEntity = null;
    Object originalEntity = null;



    try { //    

        // do stuff before executing the call
        originalEntity = msgEntityFactory.fetch(id, Build.class);

        //execute the call
        returnedEntity = pjp.proceed();

        // do stuff after executing the call
        // ...

    } catch (Throwable e) {
        e.printStackTrace();
    }
    return returnedEntity;
}

@Override
public int getOrder() {
    return 2;
}

}

还有我的dao片段

@Repository 公共类JpaBuildDao实现了BuildDao {

private static final Log log = LogFactory.getLog(JpaBuildDao.class);

@PersistenceContext
private EntityManager entityManager;

private QueryHelper queryHelper;
private BuildQueryFactory standardQueryFactory;
private PartDao partDao;

public Build getFlatBuild(Integer id) {
    Build returnBuild;

        Query query = entityManager.createQuery(
                "SELECT b FROM Build b " + 
                "WHERE " +
                "b.id = :id");
        query.setParameter("id", id);
        returnBuild =  (Build) query.getSingleResult();


    return returnBuild;
}

1 个答案:

答案 0 :(得分:1)

取得了一些进展。真正的问题是buildDao被原始注入切入点,没有实例化entityManager所需的Jpa代理。

事实证明只有在另一个配置细节进入混合时才会出现问题。我还有两个将bean注入我的切入点的MethodInvokingFactoryBean实例:

<bean id="registerListenerJms"
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
        <ref local="messagePointcut" />
    </property>
    <property name="targetMethod">
        <value>registerObserver</value>
    </property>
    <property name="arguments">
        <list>
            <ref bean="jmsGateway" />
        </list>
    </property>
</bean>

<bean id="registerListenerAmf"
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
        <ref local="messagePointcut" />
    </property>
    <property name="targetMethod">
        <value>registerObserver</value>
    </property>
    <property name="arguments">
        <list>
            <ref bean="amfGateway" />
        </list>
    </property>
</bean> 

当我删除这两个bean时,我的切入点没有获得原始代理,但是它获得了一个带有dao引用的JdkDynamicAopProxy。

不知道为什么MethodInvokingFactoryBean会混淆注入dao,但确实如此。

底线是暂时我正在删除实现我的观察者模式的MethodInvokingFactoryBean,并且在要挂钩的bean上使用切入点的依赖项。

不是一个完整的解决方案,而是一个可接受的解决方法。