2013-02-16 55 views
0

我正在尝试编写一个持久性测试。我有一个Maven项目,并使用Arquillian作为我的商店,内嵌Glassfish容器,Hibernate(作为我的JPA提供程序)和HSQLDB。使用JPA与hsqldb休眠语法异常

当我运行我的测试,我得到一个语法例外(我可以张贴如果需要完整的堆栈跟踪:

javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException: Syntax error: Encountered "identity" at line 1, column 6. 

日志似乎表明该表中创建正确:

Hibernate: 
    create table Game (
     id bigint generated by default as identity (start with 1), 
     title varchar(50) not null, 
     primary key (id) 
    ) 
Dumping old records... 
Hibernate: 
    delete 
    from 
     Game 
Inserting records... 
Hibernate: 
    insert 
    into 
     Game 
     (id, title) 
    values 
     (default, ?) 
Hibernate: 
    drop table Game if exists 
Hibernate: 
    drop table Member if exists 

我已包含我认为相关的文件

  • persistence.xml
  • 的pom.xml
  • 实体类
  • 测试类

的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="testPU" transaction-type="JTA"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <class>Member</class> 
    <class>Game</class> 
    <exclude-unlisted-classes>true</exclude-unlisted-classes> 
    <properties> 

     <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"  /> 
     <property name="javax.persistence.jdbc.url"  value="jdbc:hsqldb:mem:demodb" /> 
     <property name="javax.persistence.jdbc.user" value="sa" /> 
     <property name="javax.persistence.jdbc.password" value="" /> 


     <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"  /> 
     <property name="hibernate.hbm2ddl.auto" value="create-drop" /> 
     <property name="hibernate.show_sql" value="true" /> 
     <property name="hibernate.format_sql" value="true" /> 

    </properties> 
</persistence-unit> 
</persistence> 

的pom.xml

<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>....</groupId> 
    <artifactId>....</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>war</packaging> 

    <name>Web App</name> 

    <properties> 
     <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
     <netbeans.hint.deploy.server>gfv3ee6</netbeans.hint.deploy.server> 
     <arquillian.version>1.0.0.Alpha2</arquillian.version> 
    </properties> 

    <dependencies> 

     <dependency> 
      <groupId>org.hsqldb</groupId> 
      <artifactId>hsqldb</artifactId> 
      <version>2.2.9</version> 
      <scope>test</scope> 
     </dependency> 
     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.10</version> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>org.jboss.arquillian.junit</groupId> 
      <artifactId>arquillian-junit-container</artifactId> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-entitymanager</artifactId> 
      <version>4.1.9.Final</version> 
     </dependency> 

    </dependencies> 

    <dependencyManagement> 
     <dependencies> 
      <dependency> 
       <groupId>org.jboss.arquillian</groupId> 
       <artifactId>arquillian-bom</artifactId> 
       <version>1.0.3.Final</version> 
       <scope>import</scope> 
       <type>pom</type> 
      </dependency> 
     </dependencies> 
    </dependencyManagement> 

    <profiles> 
     <profile> 
      <id>arquillian-glassfish-embedded</id> 
      <dependencies> 
       <dependency> 
        <groupId>org.jboss.arquillian.container</groupId> 
        <artifactId>arquillian-glassfish-embedded-3.1</artifactId> 
        <version>1.0.0.CR3</version> 
        <scope>test</scope> 
       </dependency> 
       <dependency> 
        <groupId>org.glassfish.main.extras</groupId> 
        <artifactId>glassfish-embedded-all</artifactId> 
        <version>3.1.2</version> 
        <scope>provided</scope> 
       </dependency> 
      </dependencies> 
     </profile> 
    </profiles> 

    <build> 
     <plugins> 
      <plugin> 
       <artifactId>maven-surefire-plugin</artifactId> 
       <version>2.13</version> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>2.3.2</version> 
       <configuration> 
        <source>1.6</source> 
        <target>1.6</target> 
        <compilerArguments> 
         <endorseddirs>${endorsed.dir}</endorseddirs> 
        </compilerArguments> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-jar-plugin</artifactId> 
       <version>2.4</version> 
       <configuration> 
        <source>1.6</source> 
        <target>1.6</target> 
        <compilerArguments> 
         <endorseddirs>${endorsed.dir}</endorseddirs> 
        </compilerArguments> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-war-plugin</artifactId> 
       <version>2.1</version> 
       <configuration> 
        <failOnMissingWebXml>false</failOnMissingWebXml> 
       </configuration> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-dependency-plugin</artifactId> 
       <version>2.1</version> 
       <executions> 
        <execution> 
         <phase>validate</phase> 
         <goals> 
          <goal>copy</goal> 
         </goals> 
         <configuration> 
          <outputDirectory>${endorsed.dir}</outputDirectory> 
          <silent>true</silent> 
          <artifactItems> 
           <artifactItem> 
            <groupId>javax</groupId> 
            <artifactId>javaee-endorsed-api</artifactId> 
            <version>6.0</version> 
            <type>jar</type> 
           </artifactItem> 
          </artifactItems> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
     </plugins> 
     <finalName>....</finalName> 
    </build> 

    <repositories> 
     <repository> 
      <url>http://download.java.net/maven/2/</url> 
      <id>hibernate-support</id> 
      <layout>default</layout> 
      <name>Repository for library Library[hibernate-support]</name> 
     </repository> 
     <repository> 
      <url>http://ftp.ing.umu.se/mirror/eclipse/rt/eclipselink/maven.repo</url> 
      <id>eclipselink</id> 
      <layout>default</layout> 
      <name>Repository for library Library[eclipselink]</name> 
     </repository> 
    </repositories> 
</project> 

实体

//imports removed 

@Entity 
public class Game implements Serializable { 
    @Id @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 
    private String title; 

    public Game() {} 

    public Game(String title) { 
     this.title = title; 
    } 


    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 "[email protected]" + hashCode() + "[id = " + id + "; title = " + title + "]"; 
    } 
} 

* 测试类

//imports removed 

@RunWith(Arquillian.class) 
public class GamePersistenceTest { 

    @Deployment 
    public static Archive<?> createDeployment() { 
     return ShrinkWrap.create(WebArchive.class, "test.war") 
       .addPackage(Game.class.getPackage()) 
       .addAsResource("META-INF/persistence.xml") 
       .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml"); 
    } 
    private static final String[] GAME_TITLES = { 
     "Super Mario Brothers", 
     "Mario Kart", 
     "F-Zero" 
    }; 
    @PersistenceContext 
    EntityManager em; 

    @Inject 
    UserTransaction utx; 

    // tests go here 
    @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))); 
    } 

    @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(); 
     // clear the persistence context (first-level cache) 
     em.clear(); 
    } 

    private void startTransaction() throws Exception { 
     utx.begin(); 
     em.joinTransaction(); 
    } 

    @After 
    public void commitTransaction() throws Exception { 
     utx.commit(); 
    } 
} 

回答

0

这是我的persistence.xml问题。我相信我缺少db URL上的一个属性来创建DB create=true。我也一路上抛弃了JPA配置来支持Hibernate的属性。虽然,我还没有测试过,但我预计只需要第一次更改。我的工作文件在以下情况下任何人都需要它。

<?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="testPU" transaction-type="JTA"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 
     <class>Member</class> 
     <class>Game</class> 
     <exclude-unlisted-classes>true</exclude-unlisted-classes> 
     <properties> 
      <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:demodb;create=true"/> 
      <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect"/> 
      <property name="hibernate.hbm2ddl.auto" value="create-drop"/> 
      <property name="hibernate.show_sql" value="true" /> 
      <property name="hibernate.format_sql" value="true" /> 
      <property name="hibernate.connection.username" value="sa"/> 
      <property name="hibernate.connection.password" value=""/>   
     </properties> 
    </persistence-unit> 

</persistence> 
+1

'create = true'应该不是必须的,因为该属性默认为true。当你想要确保在新的连接尝试时已经创建了数据库时,使用'create = false' – fredt 2013-02-16 08:08:58

+0

@fredt感谢您的更新。当时我一直在进行一些修改,但没有机会重新访问它。如果需要,我会稍后重新测试并发布EDIT – Romski 2013-02-19 01:51:39