Невозможно отобразить список <String>по Hibernate в PostgreSql - PullRequest
0 голосов
/ 22 февраля 2020

Я бы хотел легко подумать - отобразить список String в базе данных, используя hibernate. Я могу сделать это, когда мой hibernate.hbm2ddl.auto настроен на создание или создание-удаление. Если я изменяю его, чтобы обновить, это выдает мне ошибку во время сборки Session Factory. Я проверил, что столбцы в БД существуют. Во время отладки я обнаружил, что в SchemaMigratorImpl.doMigrationToTargets метод Hibernate в поле имен полей primaryKey для таблицы ITEM_POSITIONS поврежден.

Кто-нибудь знает, что я делаю неправильно?

Stacktrace:

Exception in thread "main" javax.persistence.PersistenceException: [PersistenceUnit: HelloWorldPU] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:877)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:805)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:58)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at util.HibernateUtil.getEntityManagerFactory(HibernateUtil.java:43)
    at TestApp.main(TestApp.java:12)
Caused by: org.hibernate.exception.SQLGrammarException: Error accessing column metadata: ITEM_POSITIONS
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:95)
    at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.convertSQLException(InformationExtractorJdbcDatabaseMetaDataImpl.java:71)
    at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getForeignKeys(InformationExtractorJdbcDatabaseMetaDataImpl.java:631)
    at org.hibernate.tool.schema.extract.internal.TableInformationImpl.foreignKeys(TableInformationImpl.java:88)
    at org.hibernate.tool.schema.extract.internal.TableInformationImpl.getForeignKey(TableInformationImpl.java:99)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.findMatchingForeignKey(SchemaMigratorImpl.java:338)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.applyForeignKeys(SchemaMigratorImpl.java:318)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigrationToTargets(SchemaMigratorImpl.java:157)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:59)
    at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:129)
    at org.hibernate.tool.hbm2ddl.SchemaUpdate.execute(SchemaUpdate.java:97)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:481)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:802)
    ... 5 more
Caused by: org.postgresql.util.PSQLException: ERROR: column t1.tgconstrname does not exists
  Pozycja: 113
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:374)
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:254)
    at org.postgresql.jdbc2.AbstractJdbc2DatabaseMetaData.getImportedExportedKeys(AbstractJdbc2DatabaseMetaData.java:3373)
    at org.postgresql.jdbc2.AbstractJdbc2DatabaseMetaData.getImportedKeys(AbstractJdbc2DatabaseMetaData.java:3566)
    at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getForeignKeys(InformationExtractorJdbcDatabaseMetaDataImpl.java:580)
    ... 16 more

Конфигурация:

Java 8 PostgreSql: postgresql -12.1-3- windows -x64

пом. xml:

<?xml version="1.0" encoding="UTF-8"?>
<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>hibernatemapping</groupId>
    <artifactId>hibernatemapping</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>7</source>
                    <target>7</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.1-901.jdbc4</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>5.0.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.0.0.Final</version>
        </dependency>
    </dependencies>
</project>

постоянство. xml:

<persistence
        version="2.1"
        xmlns="http://xmlns.jcp.org/xml/ns/persistence"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence_2_1.xsd">

    <persistence-unit name="HelloWorldPU">
        <class>domain.Item</class>

        <exclude-unlisted-classes>true</exclude-unlisted-classes>
        <properties>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.use_sql_comments" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/hibernate_db?useSSL=false"/>
            <property name="javax.persistence.jdbc.user" value="postgres"/>
            <property name="javax.persistence.jdbc.password" value="admin"/>
        </properties>
    </persistence-unit>
</persistence>

Класс HibernateUtil, который отвечает за создание EntityManager:

package util;

import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.service.ServiceRegistry;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import java.util.Properties;

public class HibernateUtil {
    private static SessionFactory sessionFactory;
    private static EntityManagerFactory entityManagerFactory;

    public static SessionFactory getSessionFactory() {
        if (sessionFactory == null) {
            try {
                Configuration configuration = new Configuration();
                // Hibernate settings equivalent to hibernate.cfg.xml's properties
                Properties settings = new Properties();
                settings.put(Environment.DRIVER, "org.postgresql.Driver");
                settings.put(Environment.URL, "jdbc:postgresql://localhost:5432/hibernate_db?useSSL=false");
                settings.put(Environment.USER, "postgres");
                settings.put(Environment.PASS, "admin");
                settings.put(Environment.SHOW_SQL, "true");
                settings.put(Environment.CURRENT_SESSION_CONTEXT_CLASS, "thread");
                settings.put(Environment.HBM2DDL_AUTO, "auto-update");
                configuration.setProperties(settings);
                ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                        .applySettings(configuration.getProperties()).build();
                sessionFactory = configuration.buildSessionFactory(serviceRegistry);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return sessionFactory;
    }

    public static EntityManagerFactory getEntityManagerFactory(){
        if (entityManagerFactory == null) {
            entityManagerFactory = Persistence.createEntityManagerFactory("HelloWorldPU");
        }
        return entityManagerFactory;
    }
}

Класс сущности:

package domain;

import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.*;

import javax.persistence.Entity;
import javax.persistence.*;
import java.util.*;

@Entity
public class Item {

    @Id
    @GeneratedValue(generator = "ID_GENERATOR")
    @GenericGenerator(name = "ID_GENERATOR",
            strategy = "enhanced-sequence",
            parameters = {
            @Parameter(name = "sequence_name",
            value = "Item_sequence")
    })
    private Long id;
    private String name;

    @ElementCollection
    @CollectionTable(name = "ITEM_POSITIONS")
    @OrderColumn
    @Column(name = "POSITIONS")
    protected List<String> positions = new ArrayList<>();

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getPositions() {
        return positions;
    }

    public void setPositions(List<String> positions) {
        this.positions = positions;
    }
}

Test класс:

import domain.Item;
import util.HibernateUtil;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import java.util.ArrayList;
import java.util.List;

public class TestApp {
    public static void main(String[] args){
        EntityManagerFactory emf = HibernateUtil.getEntityManagerFactory();
        EntityManager em = emf.createEntityManager();

        EntityTransaction transaction = em.getTransaction();
        transaction.begin();
        Item item = new Item();
        item.setName("Item1");
        List<String> positions = new ArrayList<>();
        positions.add("Position1");
        positions.add("Position2");
        positions.add("Position3");
        positions.add("Position4");
        positions.add("Position5");
        item.setPositions(positions);
        em.persist(item);
        transaction.commit();
        em.close();
        emf.close();
    }
}

Как воспроизвести:

  1. Запустить со свойством name = "hibernate.hbm2ddl.auto" value = "create"
  2. Запустить со свойством name = "hibernate.hbm2ddl.auto" value = "update"
  3. Установка точки останова в QueryExecutorImpl.receiveErrorResponse
  4. Поиск стека вызовов для SchemaMigratorImpl.doMigrationToTargets

1 Ответ

0 голосов
/ 22 февраля 2020

Я решил эту проблему. Я добавил эту строку в мое согласие. xml

<!-- JDBC connection pool (use the built-in) -->
    <property name="connection.pool_size">1</property>

И я сменил драйвер на:

<dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.2.5</version>
</dependency>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...