如何使用hibernate jpa在内存数据库中设置h2?

Posted

技术标签:

【中文标题】如何使用hibernate jpa在内存数据库中设置h2?【英文标题】:how to set up a h2 in memory database with hibernate jpa? 【发布时间】:2017-10-22 08:51:11 【问题描述】:

正在尝试建立内存中的 h2 数据库。

persistence.xml 是:

<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  -->
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    version="1.0">

    <persistence-unit name="HelloWorldPU" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>jdbc:h2:mem:test</jta-data-source>
        <class>helloworld.Message</class>
        <properties>
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"></property>
            <property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
            <property name="hibernate.archive.autodetection" value="class"/>
        </properties>
    </persistence-unit>
</persistence>

我运行的课程是:

package learnHibernate;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class HelloWorldJPA 
 public static void main(String[] args) 
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("HelloWorldPU");
    System.out.println(emf);


我收到一个错误:

原因:org.hibernate.engine.jndi.JndiException: 解析 JNDI 名称时出错 [jdbc:h2:mem:test] 在 org.hibernate.engine.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:124) 在 org.hibernate.engine.jndi.internal.JndiServiceImpl.locate(JndiServiceImpl.java:95) 在 org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.configure(DatasourceConnectionProviderImpl.java:98) 在 org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:94) 在 org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:242) 在 org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:210) 在 org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.buildJdbcConnectionAccess(JdbcEnvironmentInitiator.java:145) 在 org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:66) 在 org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) 在 org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:88) 在 org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:259) ... 14 更多 引起:javax.naming.NoInitialContextException:需要在环境或系统属性中指定类名,或作为小程序参数,或在应用程序资源文件中:java.naming.factory.initial 在 javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662) 在 javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313) 在 javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350) 在 javax.naming.InitialContext.getNameParser(InitialContext.java:505) 在 org.hibernate.engine.jndi.internal.JndiServiceImpl.parseName(JndiServiceImpl.java:118) ... 24 更多

可能是什么原因?

我该如何解决这个问题。

【问题讨论】:

【参考方案1】:

JPA 规范说:

8.2.1.5 jta-data-source,非 jta-data-source

在 Java EE 环境中,jta-data-source 和 non-jta-data-source 元素用于指定 JNDI 名称 [...]

在 Java SE 环境中,可以使用这些元素,也可以指定数据源信息 通过其他方式——取决于提供者的要求。

我不清楚这些元素在 Java SE 环境中的指定含义是什么,但显然 Hibernate 尝试访问 JNDI 并且自然会失败。

由于您已指定其他连接属性,您可以简单地设置transaction-type="RESOURCE_LOCAL"(或完全省略它,这是Java SE 的默认值),并删除&lt;jta-data-source&gt; 元素。

然后还包括以下属性,其值调整为正确的db URL:

<!-- adjust this! -->
<property name="javax.persistence.jdbc.url" value="adjust_the_value" />

【讨论】:

以上是关于如何使用hibernate jpa在内存数据库中设置h2?的主要内容,如果未能解决你的问题,请参考以下文章

如何在java中设计JPA多态关系?

如何迭代 JPA 查询结果而不将它们全部保留在内存中?

ORM 解决方案(JPA;Hibernate)与 JDBC

在 LightAdmin (Spring/JPA/Hibernate) 中使 HSQL 数据库持久化

如何使用 JPA 和 Hibernate 在 UTC 时区中存储日期/时间和时间戳

如何使用 JPA 和 Hibernate 设置默认查询超时?