开发者

JPA entityManager is null in Pointcut

I have defined a pointcut using the @Aspect annotation in my class.

I configure the pointcut using a custom annotation which I have defined in my context:

<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-开发者_JAVA技巧ref="proxiedMethods" method="interceptAnnotatedMethod"/>
    </aop:aspect>
</aop:config>

Unfortunately the entityManager inside buildDao is always null if I have a reference to buildDao in my pointcut.

Not sure what the best way to fix this would be.

I'm assuming the problem is that the weaving used (load time) is does not know how to create an entityManager from the entityManagerFactory bean.

here is a snippet of my dao context.

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

Here is my Pointcut:

@Aspect @Transactional() public class MessagePointcut implements 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;
}

}

And a snippet of my dao

@Repository public class JpaBuildDao implements 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;
}


Made some progress. The real issue is that buildDao is injected raw into the pointcut w/o the required Jpa proxy that instantiates the entityManager.

Turns out the issue only occurs when another config detail comes into the mix. I also have two MethodInvokingFactoryBean instances injecting beans into my pointcut:

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

When I remove these two beans my pointcut doesn't get the raw proxy, but it gets a JdkDynamicAopProxy with a reference to the dao.

Have no clue why MethodInvokingFactoryBean messes up injecting the dao, but it does.

Bottom line is for the time being I'm removing the MethodInvokingFactoryBean that implement my observer pattern and live with a dependency of the pointcut on the beans that want to hook in.

Not a complete solution but an acceptable workaround.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜