无法将 Hibernate 与 QuestDB 结合使用:缺少架构表

问题描述 投票:0回答:2

我正在尝试使用 Hibernate 和 Java Micronaut 框架设置 QuestDB。我无法正确映射到 Java 实体。此外,QuestDB 似乎无法在启动时生成架构表。我正在使用 postgres 驱动程序连接 QuestDB 和 Hibernate 进行映射。非常感谢任何见解,因为我深入研究文档以理解这一切。

因此,我尝试将其归结为尽可能简单。我将从错误开始。

启动时,我从 Micronaut 收到以下信息:

Caused by: org.hibernate.exception.GenericJDBCException: Unable to build DatabaseInformation
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
    at org.hibernate.tool.schema.internal.Helper.buildDatabaseInformation(Helper.java:163)
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:96)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:184)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:316)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469)
    at io.micronaut.configuration.hibernate.jpa.EntityManagerFactoryBean.hibernateSessionFactory(EntityManagerFactoryBean.java:219)
    at io.micronaut.configuration.hibernate.jpa.$EntityManagerFactoryBean$HibernateSessionFactory3Definition.build(Unknown Source)
    at io.micronaut.context.BeanDefinitionDelegate.build(BeanDefinitionDelegate.java:153)
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1979)
    ... 73 more
Caused by: org.postgresql.util.PSQLException: ERROR: table does not exist [name=information_schema.sequences]
  Position: 15
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2553)
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2285)
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:323)
    at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:473)
    at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:393)
    at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:322)
    at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:308)
    at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:284)
    at org.postgresql.jdbc.PgStatement.executeQuery(PgStatement.java:236)
    at com.zaxxer.hikari.pool.ProxyStatement.executeQuery(ProxyStatement.java:111)
    at com.zaxxer.hikari.pool.HikariProxyStatement.executeQuery(HikariProxyStatement.java)
    at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:42)
    at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.initializeSequences(DatabaseInformationImpl.java:65)
    at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.<init>(DatabaseInformationImpl.java:59)
    at org.hibernate.tool.schema.internal.Helper.buildDatabaseInformation(Helper.java:155)
    ... 82 more

在 QuestDB 日志中,它提供了更多详细信息:

2021-06-12T19:49:08.431644Z I i.q.c.p.PGConnectionContext protocol [major=3, minor=0]
2021-06-12T19:49:08.431661Z I i.q.c.p.PGConnectionContext propertry [name=user, value=admin]
2021-06-12T19:49:08.431672Z I i.q.c.p.PGConnectionContext propertry [name=admin, value=database]
2021-06-12T19:49:08.431681Z I i.q.c.p.PGConnectionContext propertry [name=database, value=qdb]
2021-06-12T19:49:08.431698Z I i.q.c.p.PGConnectionContext propertry [name=qdb, value=client_encoding]
2021-06-12T19:49:08.431709Z I i.q.c.p.PGConnectionContext propertry [name=client_encoding, value=UTF8]
2021-06-12T19:49:08.431720Z I i.q.c.p.PGConnectionContext propertry [name=UTF8, value=DateStyle]
2021-06-12T19:49:08.431730Z I i.q.c.p.PGConnectionContext propertry [name=DateStyle, value=ISO]
2021-06-12T19:49:08.431740Z I i.q.c.p.PGConnectionContext propertry [name=ISO, value=TimeZone]
2021-06-12T19:49:08.431750Z I i.q.c.p.PGConnectionContext propertry [name=TimeZone, value=America/Chicago]
2021-06-12T19:49:08.431761Z I i.q.c.p.PGConnectionContext propertry [name=America/Chicago, value=extra_float_digits]
2021-06-12T19:49:08.431771Z I i.q.c.p.PGConnectionContext propertry [name=extra_float_digits, value=2]
2021-06-12T19:49:08.431780Z I i.q.c.p.PGConnectionContext propertry [name=2, value=]
2021-06-12T19:49:08.432279Z I i.q.c.p.PGConnectionContext parse [q=SET extra_float_digits = 3]
2021-06-12T19:49:08.432493Z I i.q.c.p.PGConnectionContext parse [q=SET application_name = 'PostgreSQL JDBC Driver']
2021-06-12T19:49:08.464065Z I i.q.g.CharacterStore resize [capacity=8192]
....
PGConnectionContext error [pos=4525, msg=`too few arguments for '::' [found=1,expected=2]
...

数据库是使用下面非常简单的命令创建的。 QuestDB 的有趣之处在于没有主键支持。

CREATE TABLE genre(id LONG, name STRING);

下面列出了数据源配置和方言。请注意,我使用的是 postgres DIALECT。根据 QuestDB 文档,它应该适用于此...

micronaut:
  application:
    name: micronautguide
---

application:
  max: 50

---

datasources:
  default:
    url: jdbc:postgresql://172.17.0.3:8812/qdb
    username: admin
    password: quest
    driverClassName: org.postgresql.Driver
    sslmode: disable
---

jpa:
  default:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        show_sql: true
        dialect: org.hibernate.dialect.PostgreSQLDialect

这是用于映射的基本存储库和实体。

package example.micronaut;

import example.micronaut.domain.Genre;
import javax.inject.Singleton;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
import io.micronaut.transaction.annotation.ReadOnly;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Singleton 
public class GenreRepositoryImpl implements GenreRepository {

    private final EntityManager entityManager; 
    private final ApplicationConfiguration applicationConfiguration;

    public GenreRepositoryImpl(EntityManager entityManager,
                               ApplicationConfiguration applicationConfiguration) { // <2>
        this.entityManager = entityManager;
        this.applicationConfiguration = applicationConfiguration;
    }

    @Override
    @ReadOnly  
    public Optional<Genre> findById(@NotNull Long id) {
        return Optional.ofNullable(entityManager.find(Genre.class, id));
    }
}

这里有我们的存储库和实体映射。

package example.micronaut.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

@Entity
@Table(name = "genre")
public class Genre {

    public Genre() {}
    public Genre(@NotNull String name) {
        this.name = name;
    }

    @Id
    @NotNull
    @Column(name = "id", nullable = false)
    private long id;

    @NotNull
    @Column(name = "name", nullable = false)
    private String name;

    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;
    }

    @Override
    public String toString() {
        return "Genre{" +
            "id=" + id +
            ", name='" + name + '\'' +
            '}';
    }
}
java postgresql hibernate jpa questdb
2个回答
1
投票

QuestDB 在传输级别具有 Postgres 兼容性,因此如果您运行 QuestDB SQL 查询,您就能够取回数据。查询语言并非 100% 相同,QuestDB 错过了 Postgres 的许多架构表/视图。

使用 Postgres 驱动程序使任何 ORM 与 QuestDB 一起工作不仅仅是二进制协议兼容性,因此预计它不会工作。在这种情况下,它缺少

information_schema.sequences
表/视图。即使 QuestDB 添加了此视图(为空,不支持序列),也可能存在更多模式类型和 SQL 语法差异的查询,因此通过 Postgres 驱动程序与 QuestDB 一起使用 ORM 是相当具有挑战性的。

因此,选择是关闭所有 ORM 智能功能,例如模式查询(如果在 Micronaut 中可以的话),或者在 github 中寻求 ORM 的支持。


0
投票

我可以通过添加 ID 如何生成的注释来解决这个问题 虽然我的 id 是 QuestDB 中名为 uid 的唯一列的 uuid 类型

@Id
@GeneratedValue(strategy=GenerationType.UUID)
private String uid;

这样 Hibernate 就跳过了查询

information_schema.sequences

© www.soinside.com 2019 - 2024. All rights reserved.