CDI Transactional Interceptor无法正常工作

时间:2014-09-20 03:51:35

标签: java cdi interceptor weld

我有一个带有这些类的Java SE应用程序:

主要:

public static void main(String args[])
    {
        Weld weld = new Weld(); 
        WeldContainer container = weld.initialize(); 

        ShopCar sc = container.instance().select(ShopCar.class).get(); 
        sc.execute();
        weld.shutdown();
    }

我的DAO(未完全实施):

/**
 *
 * @author vFreitas
 * @param <T> The type T 
 */
public class JpaDAO<T> implements DAO<T>, Serializable
{
    /* The EntityManager of my connection */
    private final EntityManager em;
    /* The class to be persist */
    private final Class<T> classe;

    private ThreadLocal<EntityManager> threadLocal;

    /* Builder */
    /**
    *
    * @author info1
    * @param classe The class to that will represent T
    * @param em A new instance of EntityManager 
    */
    public JpaDAO(Class<T> classe, EntityManager em)
    {
        this.classe = classe;
        this.em = em;
        threadLocal = new ThreadLocal<>();
        threadLocal.set(em);
    }

    @Override
    @Transacional
    public void save(T entity)
    {
        //em.getTransaction().begin();
        em.persist(entity);
        //em.getTransaction().commit();
    }

...

我的DAOFactory:

public class DAOFactory<T>
{
    @Inject @MyDatabase private EntityManager em;

    @SuppressWarnings({ "rawtypes", "unchecked" })    
    @Produces
    public JpaDAO<T> createJpaDAO(InjectionPoint injectionPoint) throws 
            ClassNotFoundException 
    {    
        ParameterizedType type = (ParameterizedType) injectionPoint.getType();    
        Class classe = (Class) type.getActualTypeArguments()[0];   
        return new JpaDAO<>(classe,em);    
    }    
}

拦截器注释:

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@InterceptorBinding
public @interface Transacional 
{

}

和我的interceptorImpl:

@Interceptor
@Transacional
public class TransacionalInterceptor 
{

    @Inject @MyDatabase
    private EntityManager manager;

    @Inject private ThreadLocal<EntityManager> threadLocal;

    Logger logger = LoggerFactory.getLogger(TransacionalInterceptor.class);

    @AroundInvoke
    public Object invoke(InvocationContext context) throws Exception 
    {
        manager = threadLocal.get();
        //EntityTransaction trx = manager.getTransaction();
        if(!manager.getTransaction().isActive())
        {
            manager.getTransaction().begin();
            System.out.println("Starting transaction");
            Object result = context.proceed();
            manager.getTransaction().commit();
            System.out.println("Committing transaction");
            return result;
        }

beans.xml中:

<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd" >

    <interceptors>
        <class>shopcar.util.TransacionalInterceptor</class>
    </interceptors>
</beans>

当我保存一个实体时,它说我需要打开我的事务......所以我的拦截器没有被调用。我做了很多搜索,不知道我的代码有什么问题。我很感激一些帮助。谢谢!

1 个答案:

答案 0 :(得分:3)

好的,我不得不重新阅读你的问题才能看到问题。

问题是在你的生成器方法中,你实例化了一个DAO。因为您使用new实例化它,所以绕过了拦截器绑定。

相关问题