JndiException: Ошибка синтаксического анализа имени JNDI в автономном приложении - PullRequest
1 голос
/ 21 сентября 2019

Я пытаюсь использовать hibernate и базу данных h2 в автономном приложении без какого-либо сервера приложений.

Кроме того, я могу подключиться к базе данных h2 (используя файловый режим для тестирования) с помощью некоторого инструмента базы данных.

Я настроил свой проект как проект maven, включая следующие зависимости:

<dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.199</version>
</dependency>

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

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.4.4.Final</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.9.RELEASE</version>
</dependency>

persistence.xml (resources / META-INF / persistence.xml)

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">

    <persistence-unit name="sow-quest-unit">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <!--        <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>-->
        <!--        <jta-data-source>jdbc:h2:file:D:\Projects\SecretWoods\db</jta-data-source>-->

        <non-jta-data-source>jdbc:h2:file:D:\Projects\SecretWoods\db</non-jta-data-source>

        <properties>
            <property name="javax.persistence.jdbc.url" value="jdbc:h2:file:D:\Projects\SecretWoods\db" />
            <property name="hibernate.connection.url" value="jdbc:h2:file:D:\Projects\SecretWoods\db" />
            <property name="hibernate.connection.driver_class" value="org.h2.Driver" />
            <property name="hibernate.connection.username" value="admin" />
            <property name="hibernate.connection.password" value="admin" />
            <property name="hibernate.archive.autodetection" value="class" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
            <property name="hbm2ddl.auto" value="create" />
            <property name="transaction-type" value="RESOURCE-LOCAL"/>
        </properties>
    </persistence-unit>

</persistence>

hibernate.cfg.xml (resources / hibernate.cfg.xml)

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="connection.url">jdbc:h2:file:D:\Projects\SecretWoods\db</property>
    <property name="connection.driver_class">org.h2.Driver</property>

    <property name="hibernate.connection.url">jdbc:h2:file:D:\Projects\SecretWoods\db</property>
    <property name="hibernate.connection.driver_class">org.h2.Driver</property>
    <property name="hibernate.connection.username">admin</property>
    <property name="hibernate.connection.password">admin</property>
    <property name="hibernate.archive.autodetection">class</property>
    <property name="hibernate.show_sql">true</property>
    <property name="hibernate.format_sql">true</property>
    <property name="hbm2ddl.auto">create</property>
    <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
    <property name="transaction-type">RESOURCE-LOCAL</property>
  </session-factory>
</hibernate-configuration>

и мой код:

package com.wolfo.database;

import javax.persistence.Entity;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;

import com.wolfo.quest.QText;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class DatabaseMain {

//  @PersistenceContext(unitName = "sow-quest-unit")
//  private EntityManager entityManager;

    public void createEnitites()    {

        EntityManagerFactory emf = Persistence.createEntityManagerFactory("sow-quest-unit");
        EntityManager em = emf.createEntityManager();


        QText qText = new QText();
        qText.setText("test text");
//      entityManager.persist(qText);

    }

}

Ошибка: при попытке внедрить или создать менеджер сущностей сна фабрике управления объектами генерируются исключения:

Caused by: org.hibernate.engine.jndi.JndiException: Error parsing JNDI name [jdbc:h2:file:D:\Projects\SecretWoods\db]
    at 
    ... 17 more
Caused by: javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)

Дополнительная информация:

Я пробовал без транзакции-типа = RESOURCE-LOCAL.И я попробовал jta-источник данных, а не jta-data-source ...

После сеанса отладки причина: в JndiServiceImpl (Hibernate) есть метод

private Name parseName(String jndiName, Context context)

jndiName заполнено, но контекст кажется пустым:

Debug Window

1 Ответ

0 голосов
/ 22 сентября 2019

Кажется, что невозможно использовать EntityManager?!

Я пытался сделать следующее: удаленный persitence.xml, отредактированный hibernate.cfg.xml (добавлен следующий):

<property name="current_session_context_class">thread</property>

<property name="hibernate.dbcp.initialSize">5</property>
<property name="hibernate.dbcp.maxTotal">20</property>
<property name="hibernate.dbcp.maxIdle">10</property>
<property name="hibernate.dbcp.minIdle">5</property>
<property name="hibernate.dbcp.maxWaitMillis">-1</property>

<mapping class="com.wolfo.quest.Quest" />
<mapping class="com.wolfo.quest.QAnswer" />
<mapping class="com.wolfo.quest.QQuestion" />
<mapping class="com.wolfo.quest.QText" />

После этого я написал какой-то класс (найденный в примере):

private static StandardServiceRegistry registry;
private static SessionFactory sessionFactory;

public static SessionFactory getSessionFactory() {
    if (sessionFactory == null) {
        try {
            // Create registry
            registry = new StandardServiceRegistryBuilder().configure().build();

            // Create MetadataSources
            MetadataSources sources = new MetadataSources(registry);

            // Create Metadata
            Metadata metadata = sources.getMetadataBuilder().build();

            // Create SessionFactory
            sessionFactory = metadata.getSessionFactoryBuilder().build();

        } catch (Exception e) {
            e.printStackTrace();
            if (registry != null) {
                StandardServiceRegistryBuilder.destroy(registry);
            }
        }
    }
    return sessionFactory;
}

public static void shutdown() {
    if (registry != null) {
        StandardServiceRegistryBuilder.destroy(registry);
    }
}

Теперь он работает, но я подумал, что могу использовать EntityManager?!

...