2011-03-20 3 views
1

J'ai défini un pointcut en utilisant l'annotation @Aspect dans ma classe.JPA entityManager est null dans Pointcut

configurer le pointcut en utilisant une annotation personnalisée que je l'ai défini dans mon contexte:

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

Malheureusement, le entityManager intérieur buildDao est toujours nulle si j'ai une référence à buildDao dans mon pointcut.

Vous ne savez pas quel serait le meilleur moyen de résoudre ce problème.

Je suppose que le problème est que le tissage utilisé (temps de chargement) ne sait pas comment créer un entityManager à partir du bean entityManagerFactory.

Voici un extrait de mon contexte 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>  

Voici mon Pointcut:

@Aspect @Transactional() MessagePointcut public class implémente Ordonné, 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; 
} 

}

Et un extrait de mon dao

@Référentiel public class JpaBuildDao implémente 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; 
} 

Répondre

1

a fait quelques progrès. Le vrai problème est que buildDao est injecté brut dans le pointcut sans le proxy Jpa requis qui instancie le entityManager.

Il s'avère que le problème se produit uniquement lorsqu'un autre détail de configuration est ajouté au mixage. J'ai aussi deux cas MethodInvokingFactoryBean injectent des haricots dans mon 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> 

Lorsque je retire ces deux fèves mon pointcut ne sont pas le proxy brut, mais il obtient un JdkDynamicAopProxy avec une référence au dao.

N'avez aucune idée pourquoi MethodInvokingFactoryBean bousille injecter le dao, mais c'est le cas.

Bottom line est pour le moment je retirer la MethodInvokingFactoryBean qui mettent en œuvre mon modèle d'observation et de vivre avec une dépendance de la pointcut sur les haricots qui veulent accrocher dans.

Pas une solution complète, mais un niveau acceptable solution de contournement.

Questions connexes