无法使用 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 错误