OpenJPA

对于OpenJPA的测试场景,稍微复杂一些。

注:完整代码请见openjpa项目。

测试基类

测试基类如下,这里要得到的是EntityManager,openjpa中DAO需要的是这个EntityManager对象:

public class AbstractH2DaoTest {

    private static EntityManagerFactory emf;
    protected EntityManager entityManager;

    @Before
    public void prepareH2() throws Exception {
        if (emf == null) {
            try {
                emf = Persistence.createEntityManagerFactory("EmbeddedH2");
            } catch (Throwable e) {
                System.out.printf("******  fail to initial openJpa and H2    *******");
                e.printStackTrace();
                Assert.fail("fail to initial openJpa and H2");
            }
        }

        entityManager = emf.createEntityManager();
        entityManager.getTransaction().begin();
    }

    @After
    public void tearDown() {
        if (entityManager != null) {
            entityManager.getTransaction().commit();
            entityManager = null;
        }
    }
}

注意这里的@Before和@After两个方法中,分别做了Transaction的begin和commit。后面会介绍为什么需要如此。

persistence.xml

对应上面创建EntityManagerFactory的语句:

Persistence.createEntityManagerFactory("EmbeddedH2");

需要准备文件 src/test/resources/META-INF/persistence.xml, 内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
    xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="EmbeddedH2"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
        <class>com.github.skyao.h2demo.entity.AddressEntity</class>
        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
            <property name="javax.persistence.jdbc.url"
                value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;MODE=POSTGRESQL" />
            <property name="javax.persistence.jdbc.user" value="sa" />
            <property name="javax.persistence.jdbc.password" value="" />
            <property name="openjpa.RuntimeUnenhancedClasses" value="supported" />
            <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)" />
        </properties>
    </persistence-unit>
</persistence>

这里的 persistence-unit name="EmbeddedH2" 中的name需要和前面Persistence.createEntityManagerFactory()保持名字一致。在这种情况下,transaction-type只能填写"RESOURCE_LOCAL"。

RESOURCE_LOCAL会带来一个问题,由于没有完整的oepanjpa支持,数据库事务需要自己手工提交。因此我们不得已,只好如上面的基类代码中那样在每个测试案例执行前(@Before)begin transaction,在每个测试案例执行后(@After)commit transaction。

注意这里的H2 数据库URL中不再有建表语句的sql需要执行,这是因为opanjpa自身提供自动建表的功能,因此可以不想纯JDBC下面那边需要自己动手。

测试案例

测试案例通过继承基类得到EntityManager,注入给要测试的DAO:

public class AddressDaoImplTest extends AbstractH2DaoTest {

    private AddressDaoImpl dao;

    @Before
    public void prepareDao() {
        dao = new AddressDaoImpl();
        dao.setEntityManager(this.entityManager);
    }

    @Test
    public void testSaveAndQuery() {
        AddressEntity addressEntity =new AddressEntity();
        addressEntity.setId(100);
        addressEntity.setName("sky");
        int id = dao.save(addressEntity);
        //System.out.println(addressEntity.toString());

        AddressEntity queryEntity = dao.query(id);
        //System.out.println(queryEntity.toString());
        assertThat(queryEntity).isEqualToComparingFieldByField(addressEntity);
    }
}

results matching ""

    No results matching ""