最后,我设法使用 CDI、休眠、嵌入 TomEE 上的内存 H2 数据库来设置 Arquillian。实际上我们不需要任何resource.xml。我们只需要一个用于 CDI 的 beans.xml 和一个用于定义数据源和持久性单元的 persistence.xml。这是我的 shrinkWrap 以及我的 TomEE、H2、CDI 和 Hibernate 设置文件。
我的 ShrinkWrap 测试课
import org.apache.openejb.assembler.classic.AppInfo;
import org.apache.openejb.assembler.classic.Assembler;
import org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory;
import org.apache.openejb.jee.jba.cmp.AddColumnTemplate;
import org.apache.openejb.loader.SystemInstance;
import org.apache.openejb.spi.ContainerSystem;
import org.apache.ziplock.JarLocation;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ArchivePaths;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.shrinkwrap.resolver.api.ResolutionException;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.ScopeType;
import org.jboss.shrinkwrap.resolver.api.maven.strategy.AcceptScopesStrategy;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import se.raindance.yashar.Game;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceContextType;
import javax.persistence.PersistenceUnit;
import javax.transaction.UserTransaction;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@RunWith(Arquillian.class)
public class HibernateTest {
@Deployment
public static WebArchive war() {
File[] hibernate;
try { // try offline first since it is generally faster
hibernate = Maven.resolver()
.offline(true)
.loadPomFromFile("src/test/resources/hibernate-pom.xml")
.importRuntimeAndTestDependencies(new AcceptScopesStrategy(ScopeType.COMPILE, ScopeType.RUNTIME))
.asFile();
} catch (ResolutionException re) { // try on central
hibernate = Maven.resolver()
.loadPomFromFile("src/test/resources/hibernate-pom.xml")
.importRuntimeAndTestDependencies(new AcceptScopesStrategy(ScopeType.COMPILE, ScopeType.RUNTIME))
.asFile();
}
WebArchive webArchive = ShrinkWrap.create(WebArchive.class, "hibernate-app.war")
.addAsWebInfResource("test-persistence.xml", "classes/META-INF/persistence.xml")
.addAsWebInfResource(EmptyAsset.INSTANCE, "classes/META-INF/beans.xml")
.addAsLibraries(hibernate)
.addAsLibraries(JarLocation.jarLocation(ResolutionException.class))
.addClasses(Game.class)
.addAsLibraries(JarLocation.jarLocation(org.jboss.shrinkwrap.resolver.api.maven.filter.MavenResolutionFilter.class));
System.out.println(webArchive.toString(true));
return webArchive;
}
private static final String[] GAME_TITLES = {
"Super Mario Brothers",
"Mario Kart",
"F-Zero"
};
@PersistenceContext(unitName = "yasharUnit")
EntityManager em;
@Inject
UserTransaction utx;
@Before
public void preparePersistenceTest() throws Exception {
clearData();
insertData();
startTransaction();
}
private void clearData() throws Exception {
utx.begin();
em.joinTransaction();
System.out.println("Dumping old records...");
em.createQuery("delete from Game").executeUpdate();
utx.commit();
}
private void insertData() throws Exception {
utx.begin();
em.joinTransaction();
System.out.println("Inserting records...");
for (String title : GAME_TITLES) {
Game game = new Game(title);
em.persist(game);
}
utx.commit();
em.clear();
}
private void startTransaction() throws Exception {
utx.begin();
em.joinTransaction();
}
@After
public void commitTransaction() throws Exception {
utx.commit();
}
@Test
public void shouldFindAllGamesUsingJpqlQuery() throws Exception {
// given
String fetchingAllGamesInJpql = "select g from Game g order by g.id";
// when
System.out.println("Selecting (using JPQL)...");
List<Game> games = em.createQuery(fetchingAllGamesInJpql, Game.class).getResultList();
// then
System.out.println("Found " + games.size() + " games (using JPQL):");
assertContainsAllGames(games);
}
private static void assertContainsAllGames(Collection<Game> retrievedGames) {
Assert.assertEquals(GAME_TITLES.length, retrievedGames.size());
final Set<String> retrievedGameTitles = new HashSet<String>();
for (Game game : retrievedGames) {
System.out.println("* " + game);
retrievedGameTitles.add(game.getTitle());
}
Assert.assertTrue(retrievedGameTitles.containsAll(Arrays.asList(GAME_TITLES)));
}
}
休眠-pom.xml
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.openejb.arquillian.tests</groupId>
<version>1.0.0</version>
<artifactId>codi-deps</artifactId>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.1.6.Final</version>
<exclusions>
<exclusion>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.0-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.jboss.spec.javax.transaction</groupId>
<artifactId>jboss-transaction-api_1.1_spec</artifactId>
</exclusion>
<exclusion>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.0.Final</version>
<exclusions>
<exclusion>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
持久性.xml
<persistence 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"
version="2.0">
<persistence-unit name="yasharUnit" transaction-type="JTA">
<jta-data-source>yasharDataSource</jta-data-source>
<non-jta-data-source>yasharUnmanagedDataSource</non-jta-data-source>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>se.raindance.yashar.Game</class>
<properties>
<property name="hibernate.connection.username" value="sa" />
<property name="hibernate.connection.driver_class" value="org.h2.Driver" />
<property name="hibernate.connection.password" value="" />
<property name="hibernate.connection.url" value="jdbc:h2:~/test;AUTO_SERVER=TRUE" />
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
</properties>
</persistence-unit>
</persistence>
最后是我们的示例游戏实体
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
/**
* @author Yashar Bizhanzadeh
*
*/
@Entity
public class Game implements Serializable {
private Long id;
private String title;
public Game() {}
public Game(String title) {
this.title = title;
}
@Id @GeneratedValue
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@NotNull
@Size(min = 3, max = 50)
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return "Game@" + hashCode() +
"[id = " + id + "; title = " + title + "]";
}
}
arquillian.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<arquillian xmlns="http://jboss.org/schema/arquillian"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="tomee-embedded" default="true">
<configuration>
<property name="httpPort">-1</property>
<property name="stopPort">-1</property>
<property name="dir">target/tomee-embedded</property>
<property name="appWorkingDir">target/arquillian-embedded-working-dir</property>
<property name="portRange">20001-30000</property>
</configuration>
</container>
</arquillian>
和一个空的 beans.xml。