DeltaSpike JPA 模块

概述
JPA模块提供了事务上下文和范围,允许在事务执行的方法。

1.声明JPA模块依赖关系

添加JPA项目中模块的依赖项列表 pom.xml 文件使用此代码片段:
<dependency>
    <groupId>org.apache.deltaspike.modules</groupId>
    <artifactId>deltaspike-jpa-module-api</artifactId>
    <version>${deltaspike.version}</version>
    <scope>compile</scope>
</dependency>

<dependency>
    <groupId>org.apache.deltaspike.modules</groupId>
    <artifactId>deltaspike-jpa-module-impl</artifactId>
    <version>${deltaspike.version}</version>
    <scope>runtime</scope>
</dependency>

2.启用事务拦截器

您必须启用事务拦截器在项目 beans.xml文件,CDI 1.1+ and DeltaSpike v1.1.1+不需要:
<beans>
    <!-- Not needed with CDI 1.1+ and DeltaSpike v1.1.1+ -->
    <interceptors>
        <class>org.apache.deltaspike.jpa.impl.transaction.TransactionalInterceptor</class>
    </interceptors>
</beans>

3.使用该模块功能

@ transactional

这个注释是可以替代ejb事务.开始使用之前,它需要实现一个CDI producer EntityManager,在注入EntityManager bean中使用 @transactional。 

下面的示例显示了一个简单的producer EntityManager和相应的dispose方法。


//no javaEE Server
public class EntityManagerProducer
{
    //or manual bootstrapping
    @PersistenceContext
    private EntityManager entityManager;


    @Produces
    @RequestScoped
    protected EntityManager createEntityManager()
    {
        return this.entityManager;
    }


    protected void closeEntityManager(@Disposes EntityManager entityManager)
    {
        if (entityManager.isOpen())
        {
            entityManager.close();
        }
    }
}


//EE-Server
@ApplicationScoped
public class EntityManagerProducer
{
    @PersistenceUnit
    private EntityManagerFactory entityManagerFactory;


    @Produces
    @Default
    @RequestScoped
    public EntityManager create()
    {
        return this.entityManagerFactory.createEntityManager();
    }


    public void dispose(@Disposes @Default EntityManager entityManager)
    {
        if (entityManager.isOpen())
        {
            entityManager.close();
        }
    }
}

下面的例子显示如何使用 EntityManager,@Transactional


//bean与事务方法
public class TransactionalBean
{
    @Inject
    private EntityManager entityManager;


    @Transactional
    public void executeInTransaction()
    {
        //...
    }
}

//...
@Transactional
public class TransactionalBean
{
    @Inject
    private EntityManager entityManager;

    //...
}

也可以通过CDI stereotypes 来使用

@Stereotype
@Transactional
@ApplicationScoped
public @interface Repository
{
}


//...
@Repository
public class TransactionalBean
{
    @Inject
    private EntityManager entityManager;


    //...
}

下面是系统存在多个persistence-units的使用方法,使用cdi qualifiers进行配置使用.

//...
public class EntityManagerProducer
{
    @PersistenceContext(unitName = "firstDB")
    private EntityManager firstEntityManager;


    @PersistenceContext(unitName = "secondDB")
    private EntityManager secondEntityManager;


    @Produces
    @First
    @RequestScoped
    protected EntityManager createFirstEntityManager()
    {
        return this.firstEntityManager;
    }


    protected void closeFirstEntityManager(@Disposes @First EntityManager entityManager)
    {
        if (entityManager.isOpen())
        {
            entityManager.close();
        }
    }


    @Produces
    @Second
    @RequestScoped
    protected EntityManager createSecondEntityManager()
    {
        return this.secondEntityManager;
    }


    protected void closeSecondEntityManager(@Disposes @Second EntityManager entityManager)
    {
        if (entityManager.isOpen())
        {
            entityManager.close();
        }
    }
}


//...
public class FirstLevelTransactionBean
{
    @Inject
    private @First EntityManager firstEntityManager;


    @Inject
    private NestedTransactionBean nestedTransactionBean;


    @Transactional
    public void executeInTransaction()
    {
        //...
        this.nestedTransactionBean.executeInTransaction();
    }
}


//...
public class NestedTransactionBean
{
    @Inject
    private @Second EntityManager secondEntityManager;


    @Transactional
    public void executeInTransaction()
    {
        //...
    }
}

下面的例子是使用指定的EntityManager 

public class MultiTransactionBean
{
    @Inject
    private EntityManager defaultEntityManager;

    @Inject
    private @First EntityManager firstEntityManager;

    @Inject
    private @Second EntityManager secondEntityManager;

    @Transactional(qualifier = Default.class)
    public void executeInDefaultTransaction()
    {
    }

    @Transactional(qualifier = First.class)
    public void executeInFirstTransaction()
    {
    }

    @Transactional(qualifier = Second.class)
    public void executeInSecondTransaction()
    {
    }

    @Transactional(qualifier = {First.class, Second.class})
    public void executeInFirstAndSecondTransaction()
    {
    }
}

事务的嵌套使用

//...
public class FirstLevelTransactionBean
{
    @Inject
    private EntityManager entityManager;


    @Inject
    private NestedTransactionBean nestedTransactionBean;


    @Transactional
    public void executeInTransaction()
    {
        this.nestedTransactionBean.executeInTransaction();
    }
}


//...
public class NestedTransactionBean
{
    @Inject
    private EntityManager entityManager;


    @Transactional
    public void executeInTransaction()
    {
        //...
    }
}

如果FirstLevelTransactionBean和NestedTransactionBean使用的EntityManager不一样.那么在FirstLevelTransactionBean处将引发异常.

for example, to try an optional path instead of an immediate rollback.[它会尝试一个可选的路径去做,而不是立即回滚,如果可选的还不行,再回滚.我个人理解,不知道是否正确.]

@TransactionScoped 

略...... http://deltaspike.apache.org/documentation/jpa.html#__transactionscoped

Extended Persistence Contexts  

略..... http://deltaspike.apache.org/documentation/jpa.html#_extended_persistence_contexts 

JTA Support

EntityManager对象的事务管理方式有两种,分别为JTA和RESOURCE_LOCAL,即Java Transaction API方法和本地的事务管理。
JPA中的事务类型通过persistence.xml文件中的“transaction-type”元素配置。例如,配置事务为JTA方式的代码如下所示。
<persistence>
    <persistence-unit name="demo" transaction-type="JTA">
        //其他配置省略
    </persistence-unit>
</persistence>
如果使用RESOURCE_LOCAL管理事务,则配置代码如下所示。
<persistence>
    <persistence-unit name="demo" transaction-type="RESOURCE_LOCAL">
        //其他配置省略
    </persistence-unit>
</persistence>

除了在配置文件时指明了事务的类型,不同的事务类型,不同类型的EntityManager对象,在代码中控制事务也是不同的。

By default the transaction-type used by @Transactional is RESOURCE_LOCAL. If you configure transaction-type="JTA" in the persistence.xml file, you have to enable an alternative TransactionStrategy in the beans.xml which is called org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy.
<beans>
    <alternatives>
        <class>org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy</class>
    </alternatives>
</beans>
If you have multiple persistence-units and you have to use both transaction-types or the settings for development have to be different than the production settings, you can use org.apache.deltaspike.jpa.impl.transaction.EnvironmentAwareTransactionStrategy instead.
In case of some versions of Weld (or OpenWebBeans in BDA mode), you have to configure it as global-alternative instead of an <alternatives> in beans.xml. That means you have to add, for example, globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy =org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy to /META-INF/apache-deltaspike.properties

你可能感兴趣的:(jpa,DeltaSpike)