无法使用 JPA 在 H2 中创建表和加载数据

Posted

技术标签:

【中文标题】无法使用 JPA 在 H2 中创建表和加载数据【英文标题】:Cannot create tables and load data in H2 using JPA 【发布时间】:2014-10-15 17:31:28 【问题描述】:

我有一个使用 Hibernate 和 H2 的 JPA 项目。以下是maven pom依赖列表:

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.181</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>4.3.6.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>4.3.6.Final</version>
    </dependency>

以下是项目结构:

以下是blood_donor_create.sql的内容:

CREATE TABLE IF NOT EXISTS `blood_type` (
  `id` integer NOT NULL,
  `blood_type` char(3) NOT NULL,
  PRIMARY KEY  (`id`)
)

CREATE TABLE IF NOT EXISTS `donation` (
  `id` bigint NOT NULL auto_increment,
  `date` date NOT NULL,
  `location` varchar(150) NOT NULL,
  `donor_id` bigint NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `donation_donor` (`donor_id`),
  CONSTRAINT `donation_donor` FOREIGN KEY (`donor_id`) REFERENCES `donor` (`id`)
)

CREATE TABLE IF NOT EXISTS `donor` (
  `id` bigint NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `myanmar_name` varchar(100) NOT NULL,
  `email` varchar(50) NOT NULL,
  `facebook` varchar(50) NOT NULL,
  `phone` integer NOT NULL,
  `blood_type_id` integer NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `donor_blood_type` (`blood_type_id`),
  CONSTRAINT `donor_blood_type` FOREIGN KEY (`blood_type_id`) REFERENCES `blood_type` (`id`)
)

以下是blood_donor_load.sql的内容:

INSERT INTO `blood_type` (`id`, `blood_type`) VALUES
    (1, 'A+'),
    (2, 'A-'),
    (3, 'B+'),
    (4, 'B-'),
    (5, 'O+'),
    (6, 'O-'),
    (7, 'AB+'),
    (8, 'AB-');

以下是persistence.xml的内容:

<persistence-unit name="BloodDonorPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
        <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:h2:file:~/blooddonor"/>

        <property name="javax.persistence.schema-generation.database.action" value="create"/>
        <property name="javax.persistence.schema-generation.create-source" value="script"/>
        <property name="javax.persistence.schema-generation.create-script-source" value="sql/blood_donor_load.sql"/>
        <property name="javax.persistence.sql-load-script-source" value="sql/blood_donor_load.sql"/>
    </properties>
</persistence-unit>

运行程序会导致以下异常:

Exception in thread "main" javax.persistence.PersistenceException: Unable to execute JPA schema generation create command [INSERT INTO `blood_type` (`id`, `blood_type`) VALUES]
    at org.hibernate.jpa.internal.schemagen.GenerationTargetToDatabase.acceptCreateCommands(GenerationTargetToDatabase.java:64)
    at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator.doGeneration(JpaSchemaGenerator.java:507)
    at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator.access$300(JpaSchemaGenerator.java:69)
    at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator$Generation.execute(JpaSchemaGenerator.java:184)
    at org.hibernate.jpa.internal.schemagen.JpaSchemaGenerator.performGeneration(JpaSchemaGenerator.java:76)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:75)
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:54)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at org.bitbucket.infovillavendor.blooddonor.Launcher.main(Launcher.java:10)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.h2.jdbc.JdbcSQLException: Table "BLOOD_TYPE" not found; SQL statement:
INSERT INTO `blood_type` (`id`, `blood_type`) VALUES [42102-181]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
    at org.h2.message.DbException.get(DbException.java:179)
    at org.h2.message.DbException.get(DbException.java:155)
    at org.h2.command.Parser.readTableOrView(Parser.java:5227)
    at org.h2.command.Parser.readTableOrView(Parser.java:5204)
    at org.h2.command.Parser.parseInsert(Parser.java:1025)
    at org.h2.command.Parser.parsePrepared(Parser.java:401)
    at org.h2.command.Parser.parse(Parser.java:305)
    at org.h2.command.Parser.parse(Parser.java:277)
    at org.h2.command.Parser.prepareCommand(Parser.java:242)
    at org.h2.engine.Session.prepareLocal(Session.java:446)
    at org.h2.engine.Session.prepareCommand(Session.java:388)
    at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1189)
    at org.h2.jdbc.JdbcStatement.executeInternal(JdbcStatement.java:171)
    at org.h2.jdbc.JdbcStatement.execute(JdbcStatement.java:159)
    at org.hibernate.jpa.internal.schemagen.GenerationTargetToDatabase.acceptCreateCommands(GenerationTargetToDatabase.java:61)
    ... 18 more

这里可能有什么问题?

【问题讨论】:

【参考方案1】:

我认为您在创建或插入时不需要表名中的引号。

【讨论】:

【参考方案2】:

最好的办法是将H2 database, which has a front-end 安装到您的计算机上,然后将创建和加载语句粘贴到控制台中,这样它就可以突出显示错误并为您提供有意义的消息。

【讨论】:

以上是关于无法使用 JPA 在 H2 中创建表和加载数据的主要内容,如果未能解决你的问题,请参考以下文章

尝试在 H2 数据库中创建表时出现 Liquibase 错误

为啥我不能在我的 H2 数据库中创建表?

如何使用python在mysql中创建表和导入数据

防止用户在 H2 中创建表

使用 Android 版 PhoneGap:无法在数据库中创建表

无法在 h2 内存数据库中插入数据