Usando Hibernate ORM e JPA
Hibernate ORM is the de facto standard JPA implementation and offers you the full breadth of an Object Relational Mapper. It works beautifully in Quarkus.
Solução
Recomendamos que siga as instruções nas seções seguintes e crie a aplicação passo a passo. No entanto, você pode ir diretamente para o exemplo completo.
Clone o repositório Git: git clone https://github.com/quarkusio/quarkus-quickstarts.git, ou baixe um arquivo.
The solution is located in the hibernate-orm-quickstart directory.
Configurando e definido o Hibernate ORM
Ao usar o Hibernate ORM no Quarkus, você não precisa ter um recurso persistence.xml para configurá-lo.
Usar esse arquivo de configuração clássico é uma opção, mas desnecessária a menos que você tenha necessidades avançadas específicas.
Então veremos primeiro como o Hibernate ORM pode ser configurado sem um recurso persistence.xml.
No Quarkus, você só precisa:
-
adicionar suas configurações no
application.properties -
anotar suas entidades com
@Entitye qualquer outras anotações de mapeamento como de costume
Outras necessidades de configuração foram automatizadas: O Quarkus fará algumas escolhas opinativas e suposições bem fundamentadas.
Adicione as seguintes dependências ao seu projeto:
-
a extensão Hibernate ORM:
io.quarkus:quarkus-hibernate-orm -
A extensão do seu driver JDBC, as seguintes opções estão disponíveis:
-
quarkus-jdbc-db2para IBM DB2 -
quarkus-jdbc-derbyfor Apache Derby -
quarkus-jdbc-h2para H2 -
quarkus-jdbc-mariadbpara MariaDB -
quarkus-jdbc-mssqlpara Microsoft SQL Server -
quarkus-jdbc-mysqlpara MySQL -
quarkus-jdbc-oraclepara o Oracle Database -
quarkus-jdbc-postgresqlpara PostgreSQL
-
Por exemplo:
<!-- Hibernate ORM specific dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<!-- JDBC driver dependencies -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
// Hibernate ORM specific dependencies
implementation("io.quarkus:quarkus-hibernate-orm")
// JDBC driver dependencies
implementation("io.quarkus:quarkus-jdbc-postgresql")
Anote seus objetos persistentes com @Entity,
em seguida, adicione as propriedades de configuração relevantes em application.properties .
application.properties# datasource configuration
quarkus.datasource.db-kind = postgresql
quarkus.datasource.username = hibernate
quarkus.datasource.password = hibernate
quarkus.datasource.jdbc.url = jdbc:postgresql://localhost:5432/hibernate_db
# drop and create the database at startup (use `update` to only update the schema)
quarkus.hibernate-orm.database.generation=drop-and-create
Observe que essas propriedades de configuração não são as mesmas do arquivo de configuração típico do Hibernate ORM. Elas geralmente correspondem às propriedades de configuração do Hibernate ORM, mas podem ter nomes diferentes e não necessariamente possuem uma correspondência de 1:1 entre si.
Além disso, o Quarkus definirá automaticamente muitas definições de configuração do Hibernate ORM e, com frequência, usará padrões mais modernos.
Please see below section Hibernate ORM configuration properties for the list of properties you can set in application.properties.
Uma EntityManagerFactory será criada com base na configuração do Quarkus datasource , desde que a extensão Hibernate ORM esteja listada entre as dependências do seu projeto.
The dialect will be selected based on the JDBC driver - unless you set one explicitly.
Você pode então injetar seu EntityManager sem problemas:
@ApplicationScoped
public class SantaClausService {
@Inject
EntityManager em; (1)
@Transactional (2)
public void createGift(String giftDescription) {
Gift gift = new Gift();
gift.setName(giftDescription);
em.persist(gift);
}
}
| 1 | Injete seu gerenciador de entidades e divirta-se |
| 2 | Marque o método do seu bean CDI como @Transactional e o EntityManager será inscrito e fará o flush no commit. |
@Entity
public class Gift {
private Long id;
private String name;
@Id
@SequenceGenerator(name = "giftSeq", sequenceName = "gift_id_seq", allocationSize = 1, initialValue = 1)
@GeneratedValue(generator = "giftSeq")
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;
}
}
Para carregar instruções SQL quando o Hibernate ORM for iniciar, adicione um arquivo import.sql na raiz do seu diretório resources.
Esse script pode conter quaisquer instruções SQL DML.
Certifique-se de terminar cada instrução com um ponto e vírgula.
Isso é útil para ter um conjunto de dados pronto para seus testes ou demonstrações.
Certifique-se de envolver os métodos que modificam o banco de dados (por exemplo, entity.persist() ) em uma transação. Marcar um
método do bean CDI como @Transactional fará isso por você e tornará esse método um limite de transação. Recomendamos fazer isso
nos limites do ponto de entrada da sua aplicação, como seus controladores de endpoint REST.
|
Propriedades de configuração do Hibernate ORM
Há várias propriedades opcionais úteis para refinar seu EntityManagerFactory ou orientar suposições de Quarkus.
Não há propriedades obrigatórias, desde que uma fonte de dados padrão esteja configurada.
Quando nenhuma propriedade é definida, o Quarkus normalmente pode inferir tudo o que é necessário para configurar o Hibernate ORM e fará com que ele use a fonte de dados padrão.
The configuration properties listed here allow you to override such defaults, and customize and tune various aspects.
Propriedade de Configuração Fixa no Momento da Compilação - Todas as outras propriedades de configuração podem ser sobrepostas em tempo de execução.
Tipo |
Padrão |
|||
|---|---|---|---|---|
Whether Hibernate ORM is enabled during the build. If Hibernate ORM is disabled during the build, all processing related to Hibernate ORM will be skipped,
but it will not be possible to activate Hibernate ORM at runtime:
Environment variable: Show more |
booleano |
|
||
Environment variable: |
string |
|||
Environment variable: |
list of string |
|||
Path to a file containing the SQL statements to execute when Hibernate ORM starts. The file is retrieved from the classpath resources,
so it must be located in the resources directory (e.g. The default value for this setting differs depending on the Quarkus launch mode:
If you need different SQL statements between dev mode, test ( application.properties
Environment variable: Show more |
list of string |
|
||
Pluggable strategy contract for applying physical naming rules for database object names. Class name of the Hibernate PhysicalNamingStrategy implementation Environment variable: Show more |
string |
|||
Pluggable strategy for applying implicit naming rules when an explicit name is not given. Class name of the Hibernate ImplicitNamingStrategy implementation Environment variable: Show more |
string |
|||
Class name of a custom
Environment variable: Show more |
string |
|||
XML files to configure the entity mapping, e.g. Environment variable: Show more |
list of string |
|
||
The default in Quarkus is for 2nd level caching to be enabled, and a good implementation is already integrated for you. Just cherry-pick which entities should be using the cache. Set this to false to disable all 2nd level caches. Environment variable: Show more |
booleano |
|
||
Defines the method for multi-tenancy (DATABASE, NONE, SCHEMA). The complete list of allowed values is available in the Hibernate ORM JavaDoc. The type DISCRIMINATOR is currently not supported. The default value is NONE (no multi-tenancy). Environment variable: Show more |
string |
|||
Defines the name of the datasource to use in case of SCHEMA approach. The datasource of the persistence unit will be used if not set. Environment variable: Show more |
string |
|||
If hibernate is not auto generating the schema, and Quarkus is running in development mode then Quarkus will attempt to validate the database after startup and print a log message if there are any problems. Environment variable: Show more |
booleano |
|
||
Whether statistics collection is enabled. If 'metrics.enabled' is true, then the default here is considered true, otherwise the default is false. Environment variable: Show more |
booleano |
|||
Whether session metrics should be appended into the server log for each Hibernate session. This only has effect if statistics are enabled ( Environment variable: Show more |
booleano |
|||
Whether metrics are published if a metrics extension is enabled. Environment variable: Show more |
booleano |
|
||
Whether this persistence unit should be active at runtime. If the persistence unit is not active, it won’t start with the application, and accessing the corresponding EntityManagerFactory/EntityManager or SessionFactory/Session will not be possible. Note that if Hibernate ORM is disabled (i.e. Environment variable: Show more |
booleano |
|
||
Properties that should be passed on directly to Hibernate ORM.
Use the full configuration property key here,
for instance
Consider using a supported configuration property before falling back to unsupported ones. If none exists, make sure to file a feature request so that a supported configuration property can be added to Quarkus, and more importantly so that the configuration property is tested regularly. Environment variable: Show more |
|
|||
Tipo |
Padrão |
|||
Class name of the Hibernate ORM dialect. The complete list of bundled dialects is available in the Hibernate ORM JavaDoc.
Environment variable: Show more |
string |
|||
The storage engine to use when the dialect supports multiple storage engines. E.g. Environment variable: Show more |
string |
|||
Tipo |
Padrão |
|||
The maximum size of the query plan cache. see # Environment variable: Show more |
int |
|
||
Default precedence of null values in Valid values are: Environment variable: Show more |
|
|
||
Enables IN clause parameter padding which improves statement caching. Environment variable: Show more |
booleano |
|
||
Tipo |
Padrão |
|||
The charset of the database. Used for DDL generation and also for the SQL import scripts. Environment variable: Show more |
|
|||
Whether Hibernate should quote all identifiers. Environment variable: Show more |
booleano |
|
||
Select whether the database schema is generated or not. Environment variable: Show more |
string |
|
||
If Hibernate ORM should create the schemas automatically (for databases supporting them). Environment variable: Show more |
booleano |
|
||
Whether we should stop on the first error when applying the schema. Environment variable: Show more |
booleano |
|
||
The default catalog to use for the database objects. Environment variable: Show more |
string |
|||
The default schema to use for the database objects. Environment variable: Show more |
string |
|||
Tipo |
Padrão |
|||
The time zone pushed to the JDBC driver. Environment variable: Show more |
string |
|||
How many rows are fetched at a time by the JDBC driver. Environment variable: Show more |
int |
|||
The number of updates (inserts, updates and deletes) that are sent by the JDBC driver at one time for execution. Environment variable: Show more |
int |
|||
Tipo |
Padrão |
|||
The size of the batches used when loading entities and collections.
Environment variable: Show more |
int |
|
||
The maximum depth of outer join fetch tree for single-ended associations (one-to-one, many-to-one). A Environment variable: Show more |
int |
|||
Tipo |
Padrão |
|||
The maximum time before an object of the cache is considered expired. Environment variable: Show more |
||||
The maximum number of objects kept in memory in the cache. Environment variable: Show more |
long |
|||
Tipo |
Padrão |
|||
Existing applications rely (implicitly or explicitly) on Hibernate ignoring any DiscriminatorColumn declarations on joined inheritance hierarchies. This setting allows these applications to maintain the legacy behavior of DiscriminatorColumn annotations being ignored when paired with joined inheritance. Environment variable: Show more |
booleano |
|
||
Tipo |
Padrão |
|||
Environment variable: |
string |
|||
Environment variable: |
list of string |
|||
Path to a file containing the SQL statements to execute when Hibernate ORM starts. The file is retrieved from the classpath resources,
so it must be located in the resources directory (e.g. The default value for this setting differs depending on the Quarkus launch mode:
If you need different SQL statements between dev mode, test ( application.properties
Environment variable: Show more |
list of string |
|
||
Pluggable strategy contract for applying physical naming rules for database object names. Class name of the Hibernate PhysicalNamingStrategy implementation Environment variable: Show more |
string |
|||
Pluggable strategy for applying implicit naming rules when an explicit name is not given. Class name of the Hibernate ImplicitNamingStrategy implementation Environment variable: Show more |
string |
|||
Class name of a custom
Environment variable: Show more |
string |
|||
XML files to configure the entity mapping, e.g. Environment variable: Show more |
list of string |
|
||
The default in Quarkus is for 2nd level caching to be enabled, and a good implementation is already integrated for you. Just cherry-pick which entities should be using the cache. Set this to false to disable all 2nd level caches. Environment variable: Show more |
booleano |
|
||
Defines the method for multi-tenancy (DATABASE, NONE, SCHEMA). The complete list of allowed values is available in the Hibernate ORM JavaDoc. The type DISCRIMINATOR is currently not supported. The default value is NONE (no multi-tenancy). Environment variable: Show more |
string |
|||
Defines the name of the datasource to use in case of SCHEMA approach. The datasource of the persistence unit will be used if not set. Environment variable: Show more |
string |
|||
If hibernate is not auto generating the schema, and Quarkus is running in development mode then Quarkus will attempt to validate the database after startup and print a log message if there are any problems. Environment variable: Show more |
booleano |
|
||
Whether this persistence unit should be active at runtime. If the persistence unit is not active, it won’t start with the application, and accessing the corresponding EntityManagerFactory/EntityManager or SessionFactory/Session will not be possible. Note that if Hibernate ORM is disabled (i.e. Environment variable: Show more |
booleano |
|
||
Properties that should be passed on directly to Hibernate ORM.
Use the full configuration property key here,
for instance
Consider using a supported configuration property before falling back to unsupported ones. If none exists, make sure to file a feature request so that a supported configuration property can be added to Quarkus, and more importantly so that the configuration property is tested regularly. Environment variable: Show more |
|
|||
Tipo |
Padrão |
|||
Class name of the Hibernate ORM dialect. The complete list of bundled dialects is available in the Hibernate ORM JavaDoc.
Environment variable: Show more |
string |
|||
The storage engine to use when the dialect supports multiple storage engines. E.g. Environment variable: Show more |
string |
|||
Tipo |
Padrão |
|||
The maximum size of the query plan cache. see # Environment variable: Show more |
int |
|
||
Default precedence of null values in Valid values are: Environment variable: Show more |
|
|
||
Enables IN clause parameter padding which improves statement caching. Environment variable: Show more |
booleano |
|
||
Tipo |
Padrão |
|||
The charset of the database. Used for DDL generation and also for the SQL import scripts. Environment variable: Show more |
|
|||
Whether Hibernate should quote all identifiers. Environment variable: Show more |
booleano |
|
||
Select whether the database schema is generated or not. Environment variable: Show more |
string |
|
||
If Hibernate ORM should create the schemas automatically (for databases supporting them). Environment variable: Show more |
booleano |
|
||
Whether we should stop on the first error when applying the schema. Environment variable: Show more |
booleano |
|
||
The default catalog to use for the database objects. Environment variable: Show more |
string |
|||
The default schema to use for the database objects. Environment variable: Show more |
string |
|||
Tipo |
Padrão |
|||
The time zone pushed to the JDBC driver. Environment variable: Show more |
string |
|||
How many rows are fetched at a time by the JDBC driver. Environment variable: Show more |
int |
|||
The number of updates (inserts, updates and deletes) that are sent by the JDBC driver at one time for execution. Environment variable: Show more |
int |
|||
Tipo |
Padrão |
|||
The size of the batches used when loading entities and collections.
Environment variable: Show more |
int |
|
||
The maximum depth of outer join fetch tree for single-ended associations (one-to-one, many-to-one). A Environment variable: Show more |
int |
|||
Tipo |
Padrão |
|||
The maximum time before an object of the cache is considered expired. Environment variable: Show more |
||||
The maximum number of objects kept in memory in the cache. Environment variable: Show more |
long |
|||
Tipo |
Padrão |
|||
Existing applications rely (implicitly or explicitly) on Hibernate ignoring any DiscriminatorColumn declarations on joined inheritance hierarchies. This setting allows these applications to maintain the legacy behavior of DiscriminatorColumn annotations being ignored when paired with joined inheritance. Environment variable: Show more |
booleano |
|
||
Tipo |
Padrão |
|||
Select whether the database schema DDL files are generated or not. Accepted values: Environment variable: Show more |
string |
|
||
Filename or URL where the database create DDL file should be generated. Environment variable: Show more |
string |
|||
Filename or URL where the database drop DDL file should be generated. Environment variable: Show more |
string |
|||
Tipo |
Padrão |
|||
Show SQL logs and format them nicely. Setting it to true is obviously not recommended in production. Environment variable: Show more |
booleano |
|
||
Format the SQL logs if SQL log is enabled Environment variable: Show more |
booleano |
|
||
Whether JDBC warnings should be collected and logged. Environment variable: Show more |
booleano |
|
||
If set, Hibernate will log queries that took more than specified number of milliseconds to execute. Environment variable: Show more |
long |
|||
Tipo |
Padrão |
|||
Logs SQL bind parameters. Setting it to true is obviously not recommended in production. Environment variable: Show more |
booleano |
|
||
Show SQL logs and format them nicely. Setting it to true is obviously not recommended in production. Environment variable: Show more |
booleano |
|
||
Format the SQL logs if SQL log is enabled Environment variable: Show more |
booleano |
|
||
Whether JDBC warnings should be collected and logged. Environment variable: Show more |
booleano |
|
||
If set, Hibernate will log queries that took more than specified number of milliseconds to execute. Environment variable: Show more |
long |
|||
Tipo |
Padrão |
|||
Select whether the database schema DDL files are generated or not. Accepted values: Environment variable: Show more |
string |
|
||
Filename or URL where the database create DDL file should be generated. Environment variable: Show more |
string |
|||
Filename or URL where the database drop DDL file should be generated. Environment variable: Show more |
string |
|
About the Duration format
The format for durations uses the standard You can also provide duration values starting with a number.
In this case, if the value consists only of a number, the converter treats the value as seconds.
Otherwise, |
|
Do not mix |
|
Want to start a PostgreSQL server on the side with Docker?
This will start a non-durable empty database: ideal for a quick experiment! |
Múltiplas unidades de persistência
Configuração de várias unidades de persistência
É possível definir várias unidades de persistência usando as propriedades de configuração do Quarkus.
As propriedades na raiz do namespace quarkus.hibernate-orm. definem a unidade de persistência padrão.
Por exemplo, o snippet a seguir define uma fonte de dados padrão e uma unidade de persistência padrão:
quarkus.datasource.db-kind=h2
quarkus.datasource.jdbc.url=jdbc:h2:mem:default;DB_CLOSE_DELAY=-1
quarkus.hibernate-orm.database.generation=drop-and-create
Usando uma abordagem baseada em mapa, é possível definir unidades de persistência nomeadas:
quarkus.datasource."users".db-kind=h2 (1)
quarkus.datasource."users".jdbc.url=jdbc:h2:mem:users;DB_CLOSE_DELAY=-1
quarkus.datasource."inventory".db-kind=h2 (2)
quarkus.datasource."inventory".jdbc.url=jdbc:h2:mem:inventory;DB_CLOSE_DELAY=-1
quarkus.hibernate-orm."users".database.generation=drop-and-create (3)
quarkus.hibernate-orm."users".datasource=users (4)
quarkus.hibernate-orm."users".packages=org.acme.model.user (5)
quarkus.hibernate-orm."inventory".database.generation=drop-and-create (6)
quarkus.hibernate-orm."inventory".datasource=inventory
quarkus.hibernate-orm."inventory".packages=org.acme.model.inventory
| 1 | Defina uma fonte de dados chamada users. |
| 2 | Defina uma fonte de dados chamada inventory. |
| 3 | Defina uma unidade de persistência chamada users. |
| 4 | Definir a fonte de dados usada pela unidade de persistência. |
| 5 | Essa propriedade de configuração é importante, mas a discutiremos um pouco mais adiante. |
| 6 | Defina uma unidade de persistência chamada inventory apontando para a fonte de dados inventory . |
|
Você pode misturar a fonte de dados padrão e as fontes de dados nomeadas ou ter apenas uma ou outra. |
|
A unidade de persistência padrão aponta para a fonte de dados padrão por padrão.
Para unidades de persistência nomeadas, a propriedade É perfeitamente válido ter várias unidades de persistência apontando para a mesma fonte de dados. |
Anexar classes de modelo a unidades de persistência
Há duas maneiras de anexar classes de modelo a unidades de persistência, e elas não devem ser misturadas:
-
Por meio da propriedade de configuração
packages; -
Por meio da anotação em nível de pacote
@io.quarkus.hibernate.orm.PersistenceUnit.
Se ambos forem misturados, as anotações serão ignoradas e somente as propriedades de configuração do packages serão levadas em conta.
Usar a propriedade de configuração packages é simples:
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.hibernate-orm.packages=org.acme.model.defaultpu
quarkus.hibernate-orm."users".database.generation=drop-and-create
quarkus.hibernate-orm."users".datasource=users
quarkus.hibernate-orm."users".packages=org.acme.model.user
Esse snippet de configuração criará duas unidades de persistência:
-
O padrão que conterá todas as classes de modelo no pacote
org.acme.model.defaultpu, incluindo os subpacotes. -
Uma unidade de persistência nomeada
usersque conterá todas as classes de modelo do pacoteorg.acme.model.user, incluindo os subpacotes.
Você pode anexar vários pacotes a uma unidade de persistência:
quarkus.hibernate-orm."users".packages=org.acme.model.shared,org.acme.model.user
Todas as classes de modelo dos pacotes org.acme.model.shared e org.acme.model.user serão vinculadas à unidade de persistência users .
Também é suportado vincular uma determinada classe de modelo a várias unidades de persistência.
|
As classes de modelo precisam ser adicionadas de forma consistente a uma determinada unidade de persistência. Isso significa que todas as classes de modelo dependentes de uma determinada entidade (superclasses mapeadas, embeddables…) precisam estar vinculadas à unidade de persistência. Como estamos lidando com a unidade de persistência no nível do pacote, isso deve ser bastante simples. |
|
Entidades Panache podem ser vinculadas a apenas uma unidade de persistência. Para entidades vinculadas a várias unidades de persistência, não é possível utilizar o Panache. É possível, no entanto, combinar as duas abordagens e mesclar entidades Panache e entidades tradicionais quando múltiplas unidades de persistência forem necessárias. Se você tiver um caso de uso para isso e ideias inteligentes sobre como implementá-lo sem poluir a abordagem simplificada do Panache, entre em contato pelo lista de discussão quarkus-dev. |
A segunda abordagem para vincular classes de modelo a uma unidade de persistência é utilizar anotações @io.quarkus.hibernate.orm.PersistenceUnit no nível de pacote.
Novamente, as duas abordagens não podem ser combinadas.
Para obter uma configuração semelhante à acima com a propriedade de configuração packages, crie um arquivo package-info.java com o seguinte conteúdo:
@PersistenceUnit("users") (1)
package org.acme.model.user;
import io.quarkus.hibernate.orm.PersistenceUnit;
| 1 | Be careful, use the @io.quarkus.hibernate.orm.PersistenceUnit annotation, not the JPA one. |
|
Suportamos apenas a definição de |
Observe que, de forma semelhante ao que fazemos com a propriedade de configuração, levamos em consideração o pacote anotado e também todos os seus subpacotes.
Integração com CDI
Se você já está familiarizado com o uso do Hibernate ORM no Quarkus, provavelmente já injetou o EntityManager via CDI:
@Inject
EntityManager entityManager;
Isso injetará o EntityManager da unidade de persistência padrão.
Injetar o EntityManager de uma unidade de persistência nomeada (users em nosso exemplo) é tão simples quanto:
@Inject
@PersistenceUnit("users") (1)
EntityManager entityManager;
| 1 | Aqui, novamente, usamos a mesma anotação @io.quarkus.hibernate.orm.PersistenceUnit. |
Você pode injetar o EntityManagerFactory de uma unidade de persistência nomeada utilizando o mesmo mecanismo:
@Inject
@PersistenceUnit("users")
EntityManagerFactory entityManagerFactory;
Configurando o Hibernate ORM com um persistence.xml
Alternatively, you can use a META-INF/persistence.xml to set up Hibernate ORM.
This is useful for:
-
migrating existing code
-
when you have relatively complex settings requiring the full flexibility of the configuration
-
or if you like it the good old way
|
If you have a |
As dependências pom.xml, bem como o código Java, seriam idênticos ao exemplo anterior. A única
diferença é que você especificaria a configuração do Hibernate ORM em META-INF/persistence.xml:
<persistence 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
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="CustomerPU" transaction-type="JTA">
<description>My customer entities</description>
<properties>
<!-- Connection specific -->
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQL95Dialect"/>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<!--
Optimistically create the tables;
will cause background errors being logged if they already exist,
but is practical to retain existing data across runs (or create as needed) -->
<property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
<property name="javax.persistence.validation.mode" value="NONE"/>
</properties>
</persistence-unit>
</persistence>
When using the persistence.xml configuration you are configuring Hibernate ORM directly,
so in this case the appropriate reference is the documentation on hibernate.org.
Lembre-se de que esses não são os mesmos nomes de propriedade usados no Quarkus application.properties, nem os
mesmos padrões serão aplicados.
Mapeamento XML
Hibernate ORM in Quarkus supports XML mapping.
You can add mapping files following
the orm.xml format (JPA)
or the hbm.xml format (specific to Hibernate ORM, deprecated):
-
in
application.propertiesthrough the (build-time)quarkus.hibernate-orm.mapping-filesproperty. -
em
persistence.xmlpor meio do elemento<mapping-file>.
Os arquivos de mapeamento XML são analisados no momento da compilação.
|
O arquivo Se não for isso que você deseja, use |
Definição de entidades em projetos externos ou jars
O Hibernate ORM no Quarkus depende de aprimoramentos de bytecode em tempo de compilação para suas entidades. Se você definir as entidades no mesmo projeto em que criou o aplicativo Quarkus, tudo funcionará bem.
Se as entidades vierem de projetos
ou jars externos, você pode garantir que o seu jar seja tratado como uma biblioteca de aplicação Quarkus adicionando um arquivo META-INF/beans.xml vazio.
Isso permitirá que o Quarkus indexe e aprimore suas entidades como se elas estivessem dentro do projeto atual.
Hibernate ORM no modo de desenvolvimento
O modo de desenvolvimento do Quarkus é muito útil para aplicações que combinam frontend ou serviços com acesso a banco de dados.
Há algumas abordagens comuns para tirar o melhor proveito disso.
The first choice is to use quarkus.hibernate-orm.database.generation=drop-and-create in conjunction with import.sql.
Dessa forma, a cada alteração na sua aplicação e, em particular, nas suas entidades, o schema do banco de dados será recriado corretamente
e seus dados de fixture (armazenados em import.sql) serão usados para repopulá-lo do zero.
Isso é ideal para ter controle total sobre seu ambiente e funciona perfeitamente com o modo de live reload do Quarkus:
qualquer alteração nas suas entidades ou no import.sql é imediatamente detectada e o schema é atualizado sem reiniciar a aplicação!
|
By default, in |
The second approach is to use quarkus.hibernate-orm.database.generation=update.
This approach is best when you do many entity changes but
still need to work on a copy of the production data
or if you want to reproduce a bug that is based on specific database entries.
update is a best effort from Hibernate ORM and will fail in specific situations
including altering your database structure which could lead to data loss.
For example if you change structures which violate a foreign key constraint, Hibernate ORM might have to bail out.
But for development, these limitations are acceptable.
The third approach is to use quarkus.hibernate-orm.database.generation=none.
This approach is best when you are working on a copy of the production data but want to fully control the schema evolution.
Or if you use a database schema migration tool like Flyway or Liquibase.
Com essa abordagem, ao fazer alterações em uma entidade, certifique-se de adaptar o schema do banco de dados adequadamente,
você também pode usar validate para que o Hibernate verifique se o schema corresponde às suas expectativas.
Do not use quarkus.hibernate-orm.database.generation drop-and-create and update in your production environment.
|
Essas abordagens se tornam muito poderosas quando combinadas com os perfis de configuração do Quarkus. Você pode definir diferentes perfis de configuração para selecionar comportamentos distintos dependendo do seu ambiente. Isso é excelente porque permite definir diferentes combinações de propriedades do Hibernate ORM que correspondam ao estilo de desenvolvimento que você precisa no momento.
%dev.quarkus.hibernate-orm.database.generation = drop-and-create
%dev.quarkus.hibernate-orm.sql-load-script = import-dev.sql
%dev-with-data.quarkus.hibernate-orm.database.generation = update
%dev-with-data.quarkus.hibernate-orm.sql-load-script = no-file
%prod.quarkus.hibernate-orm.database.generation = none
%prod.quarkus.hibernate-orm.sql-load-script = no-file
Você pode iniciar o modo de desenvolvimento usando um perfil personalizado:
quarkus dev -Dquarkus.profile=dev-with-data
./mvnw quarkus:dev -Dquarkus.profile=dev-with-data
./gradlew --console=plain quarkusDev -Dquarkus.profile=dev-with-data
Hibernate ORM em modo de produção
O Quarkus vem com perfis padrão ( dev , test e prod ).
E você pode adicionar seus próprios perfis personalizados para descrever vários ambientes ( staging , prod-us , etc).
A extensão Hibernate ORM Quarkus define algumas configurações padrão de forma diferente nos modos de desenvolvimento e teste do que em outros ambientes.
-
quarkus.hibernate-orm.sql-load-scripté definido comono-filepara todos os perfis, exceto os perfisdevetest.
Você pode substituí-lo explicitamente no seu application.properties
(por exemplo, %prod.quarkus.hibernate-orm.sql-load-script = import.sql ),
mas queríamos que você evitasse substituir o banco de dados por acidente no prod :)
Por falar nisso, certifique-se de não descartar o esquema do banco de dados na produção! Adicione o seguinte em seu arquivo de propriedades.
%prod.quarkus.hibernate-orm.database.generation = none
%prod.quarkus.hibernate-orm.sql-load-script = no-file
Transacionando automaticamente para o Flyway para gerenciar schemas
If you have the Flyway extension installed when running in development mode, Quarkus provides a simple way to turn your Hibernate ORM auto generated schema into a Flyway migration file. This is intended to make is easy to move from the early development phase, where Hibernate can be used to quickly set up the schema, to the production phase, where Flyway is used to manage schema changes.
Para usar esse recurso, basta abrir a Dev UI quando a extensão quarkus-flyway estiver instalada e clicar no link Datasources
no painel Flyway. Pressione o botão Create Initial Migration e ocorrerá o seguinte:
-
Um arquivo
db/migration/V1.0.0__{appname}.sqlserá criado, contendo o SQL que o Hibernate está executando para gerar o esquema -
quarkus.flyway.baseline-on-migrateserá definido, informando ao Flyway para criar automaticamente suas tabelas de linha de base -
quarkus.flyway.migrate-at-startserá definido, informando ao Flyway para aplicar automaticamente as migrações na inicialização da aplicação -
%dev.quarkus.flyway.clean-at-starte%test.quarkus.flyway.clean-at-startserão definidos para limpar o banco de dados após o recarregamento no modo dev/test
Esse botão é apenas uma conveniência para ajudá-lo a começar rapidamente com o Flyway, cabe a você determinar como deseja
gerenciar os schemas do seu banco de dados em produção. Em particular, a configuração migrate-at-start pode não ser adequada para todos os ambientes.
|
Armazenamento em cache
Aplicações que leem as mesmas entidades com frequência podem ter seu desempenho melhorado quando o cache de segundo nível do Hibernate ORM está habilitado.
Armazenamento em cache de entidades
To enable second-level cache, mark the entities that you want cached with @javax.persistence.Cacheable:
@Entity
@Cacheable
public class Country {
int dialInCode;
// ...
}
Quando uma entidade é anotada com @Cacheable, todos os seus valores de campo são armazenados em cache, exceto para coleções e relações com outras entidades.
Isso significa que a entidade pode ser carregada sem consultar o banco de dados, mas é preciso ter cuidado, pois isso implica que a entidade carregada pode não refletir as alterações recentes no banco de dados.
Armazenamento em cache de coleções e relações
Coleções e relacionamentos precisam ser anotados individualmente para serem cacheados; nesse caso, deve-se utilizar a anotação específica do Hibernate @org.hibernate.annotations.Cache, que também requer a especificação da CacheConcurrencyStrategy:
package org.acme;
@Entity
@Cacheable
public class Country {
// ...
@OneToMany
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
List<City> cities;
// ...
}
Cache de queries
As queries também podem se beneficiar do cache de segundo nível. Os resultados de queries em cache podem ser retornados imediatamente ao chamador, evitando a execução da query no banco de dados.
Tenha cuidado, pois isso implica que os resultados podem não refletir alterações recentes.
Para cachear uma query, marque-a como cacheável na instância de Query:
Query query = ...
query.setHint("org.hibernate.cacheable", Boolean.TRUE);
Se você tiver uma NamedQuery, pode habilitar o cache diretamente em sua definição, que geralmente estará em uma entidade:
@Entity
@NamedQuery(name = "Fruits.findAll",
query = "SELECT f FROM Fruit f ORDER BY f.name",
hints = @QueryHint(name = "org.hibernate.cacheable", value = "true") )
public class Fruit {
...
É só isso! A tecnologia de cache já está integrada e habilitada por padrão no Quarkus, portanto basta definir quais podem ser cacheados com segurança.
Ajuste das regiões de cache
Os caches armazenam os dados em regiões separadas para isolar diferentes porções de dados, essas regiões recebem um nome, o que é útil para configurar cada região de forma independente ou para monitorar suas estatísticas.
Por padrão, as entidades são cacheadas em regiões nomeadas de acordo com seu nome completamente qualificado, por exemplo, org.acme.Country.
As coleções são armazenadas em cache em regiões nomeadas com o nome totalmente qualificado de sua entidade proprietária e o nome do campo da coleção, separados pelo caractere #, por exemplo, org.acme.Country#cities .
Por padrão, todas as consultas em cache são mantidas em uma única região dedicada a elas, chamada default-query-results-region.
Todas as regiões são limitadas por tamanho e tempo por padrão. Os padrões são 10000 max entries e 100 seconds como tempo máximo de inatividade.
O tamanho de cada região pode ser personalizado por meio da propriedade quarkus.hibernate-orm.cache."<region_name>".memory.object-count (Substitua <region_name> pelo nome real da região).
Para definir o tempo ocioso máximo, forneça a duração (consulte a nota sobre o formato da duração abaixo) por meio da propriedade quarkus.hibernate-orm.cache."<region_name>".expiration.max-idle (Substitua <region_name> pelo nome real da região).
|
As aspas duplas são obrigatórias se o nome da região contiver um ponto. Por exemplo:
|
|
The format for durations uses the standard You can also provide duration values starting with a number.
In this case, if the value consists only of a number, the converter treats the value as seconds.
Otherwise, |
Limitações do cache
Atualmente, a tecnologia de cache fornecida pelo Quarkus é bastante rudimentar e limitada.
A equipe achou que era melhor ter algum recurso de cache para começar do que não ter nada, você pode esperar que uma solução de cache melhor seja integrada em versões futuras, e qualquer ajuda e feedback nessa área é muito bem-vinda.
|
Esses caches são mantidos localmente, portanto não são invalidados nem atualizados quando alterações são feitas no armazenamento persistente por outras aplicações. Além disso, ao executar múltiplas instâncias da mesma aplicação (em um cluster, por exemplo no Kubernetes/OpenShift), os caches em instâncias separadas da aplicação não são sincronizados. Por essas razões, habilitar o cache só é adequado quando certas premissas podem ser assumidas: recomendamos fortemente que apenas entidades, coleções e queries que nunca mudam sejam cacheadas. Ou, no máximo, que quando uma entidade for de fato modificada e permitida de ser lida de forma desatualizada (stale), isso não impacte as expectativas da aplicação. Seguir esse conselho garante que as aplicações obtenham o melhor desempenho do cache de segundo nível e, ao mesmo tempo, evitem comportamentos inesperados. Além dos dados imutáveis, em determinados contextos, pode ser aceitável habilitar o cache também em dados mutáveis, isso pode ser uma troca necessária em entidades selecionadas que são lidas com frequência e para as quais algum grau de obsoletismo é aceitável, esse "grau aceitável de obsoletismo" pode ser ajustado definindo-se as propriedades de despejo. No entanto, isso não é recomendado e deve ser feito com extremo cuidado, pois pode produzir efeitos inesperados e imprevistos nos dados. Em vez de habilitar o cache em dados mutáveis, a solução ideal seria utilizar um cache clusterizado; no entanto, no momento o Quarkus não oferece nenhuma implementação desse tipo: sinta-se à vontade para entrar em contato e informar essa necessidade para que a equipe possa levá-la em consideração. |
Por fim, o cache de segundo nível pode ser desativado globalmente ao definir hibernate.cache.use_second_level_cache como false, essa é uma configuração que precisa ser especificada no arquivo de configuração persistence.xml.
Quando o cache de segundo nível está desativado, todas as anotações de cache são ignoradas e todas as consultas são executadas ignorando os caches, isso geralmente é útil apenas para diagnosticar problemas.
Hibernate Envers
A extensão Envers do Hibernate ORM tem como objetivo fornecer uma solução fácil de auditoria/controle de versão para classes de entidades.
No Quarkus, o Envers tem uma extensão dedicada do Quarkus io.quarkus:quarkus-hibernate-envers, você só precisa adicioná-la ao seu projeto para começar a usá-la.
<!-- Add the Hibernate Envers extension -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-envers</artifactId>
</dependency>
Nesse momento, a extensão não expõe propriedades de configuração adicionais.
Para obter mais informações sobre o Hibernate Envers, consulte hibernate.org/orm/envers/ .
Métricas
Either Micrometer or SmallRye Metrics are
capable of exposing metrics that Hibernate ORM collects at runtime. To enable exposure of Hibernate metrics
on the /q/metrics endpoint, make sure your project depends on a metrics extension and set the configuration property quarkus.hibernate-orm.metrics.enabled to true.
When using SmallRye Metrics, metrics will be available under the vendor scope.
Limitações e outras informações importantes
O Quarkus não modifica as bibliotecas que utiliza, essa regra também se aplica ao Hibernate ORM: ao usar esta extensão, você terá basicamente a mesma experiência de usar a biblioteca original.
Porém, embora compartilhem o mesmo código, o Quarkus configura alguns componentes automaticamente e injeta implementações customizadas para alguns pontos de extensão, isso deve ser transparente e útil, mas se você for um especialista em Hibernate pode querer saber o que está sendo feito.
Enhancement automático em tempo de build
O Hibernate ORM pode utilizar entidades com enhancement em tempo de build, normalmente isso não é obrigatório, mas é útil e fará com que suas aplicações tenham melhor desempenho.
Normalmente, seria necessário adaptar seus scripts de build para incluir os plugins de Enhancement do Hibernate, no Quarkus isso não é necessário, pois a etapa de enhancement está integrada ao build e à análise da aplicação Quarkus.
|
Devido ao uso de aprimoramento, o uso do método Essa limitação pode ser removida no futuro. |
Integração automática
- Integração com o Transaction Manager
-
Você não precisa configurar isso, o Quarkus injeta automaticamente a referência ao Narayana Transaction Manager. A dependência é incluída automaticamente como uma dependência transitiva da extensão do Hibernate ORM. Toda a configuração é opcional, para mais detalhes, consulte Usando Transações no Quarkus.
- Pool de conexões
-
Também não é necessário escolher um. O Quarkus inclui automaticamente o pool de conexões Agroal, configure seu datasource como nos exemplos acima e ele configurará o Hibernate ORM para usar o Agroal. Mais detalhes sobre esse pool de conexões podem ser encontrados em Quarkus - Datasources.
- Cache de segundo nível
-
as explained above in section Caching, you don’t need to pick an implementation. A suitable implementation based on technologies from Infinispan and Caffeine is included as a transitive dependency of the Hibernate ORM extension, and automatically integrated during the build.
Limitações
- Mapeamento XML com arquivos duplicados no classpath
-
Espera-se que os arquivos de mapeamento XML tenham um caminho exclusivo.
In practice, it’s only possible to have duplicate XML mapping files in the classpath in very specific scenarios. For example, if two JARs include a
META-INF/orm.xmlfile (with the exact same path, but in different JARs), then the mapping file pathMETA-INF/orm.xmlcan only be referenced from apersistence.xmlin the same JAR as theMETA-INF/orm.xmlfile. - JMX
-
Management beans are not working in GraalVM native images; therefore Hibernate’s capability to register statistics and management operations with the JMX bean is disabled when compiling into a native image. This limitation is likely permanent, as it’s not a goal for native images to implement support for JMX. All such metrics can be accessed in other ways.
- Integração da JACC
-
A capacidade do Hibernate ORM de se integrar ao JACC é desativada ao criar imagens nativas do GraalVM pois o JACC não está disponível - nem é útil - no modo nativo.
- Vinculação da sessão ao contexto ThreadLocal
-
It is not possible to use the
ThreadLocalSessionContexthelper of Hibernate ORM as support for it is not implemented. Since Quarkus provides out of the box support for CDI, we believe using injection or programmatic CDI lookup to be a better approach. This feature also didn’t integrate well with reactive components and more modern context propagation techniques, making us believe this legacy feature has no future. If you badly need to bind it to a ThreadLocal it should be trivial to implement in your own code. - JNDI
-
The JNDI technology is commonly used in other runtimes to integrate different components. A common use case is Java Enterprise servers to bind the TransactionManager and the Datasource components to a name, and then have Hibernate ORM configured to look these components up by name. But in Quarkus this use case doesn’t apply as components are injected directly, making JNDI support an unnecessary legacy. As a precaution, to avoid unexpected use of JNDI, the whole support for JNDI has been disabled in the Hibernate ORM extension for Quarkus. This is both a security precaution and an optimisation.
Outras diferenças notáveis
- Formato de
import.sql -
Ao importar um
import.sqlpara configurar o banco de dados, lembre-se de que o Quarkus reconfigura o Hibernate ORM de modo a exigir um ponto e vírgula (;) para encerrar cada instrução. O padrão no Hibernate é ter uma instrução por linha, sem exigir um terminador diferente de nova linha: lembre-se de converter seus scripts para usar o caractere de terminação;se estiver reutilizando scripts existentes. Isso é útil para permitir declarações de várias linhas e formatação amigável.
Simplificando o Hibernate ORM com o Panache
A extensão Hibernate ORM with Panache facilita o uso do Hibernate ORM fornecendo entidades (e repositórios) no estilo de Active Record e concentra-se em tornar as entidades triviais e divertidas de escrever no Quarkus.
Configure sua fonte de dados
A configuração do Datasource é extremamente simples, mas é abordada em outro guia, pois tecnicamente é implementada pela extensão do pool de conexões do Agroal para o Quarkus.
Acesse Quarkus - Datasources para obter todos os detalhes.
Multitenancy
"The term multitenancy, in general, is applied to software development to indicate an architecture in which a single running instance of an application simultaneously serves multiple clients (tenants). This is highly common in SaaS solutions. Isolating information (data, customizations, etc.) pertaining to the various tenants is a particular challenge in these systems. This includes the data owned by each tenant stored in the database" (Hibernate User Guide).
Quarkus currently supports the separate database and the separate schema approach.
To see multitenancy in action, you can check out the hibernate-orm-multi-tenancy-quickstart quickstart.
Escrevendo o aplicativo
Let’s start by implementing the /{tenant} endpoint. As you can see from the source code below it is just a regular JAX-RS resource:
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
@ApplicationScoped
@Path("/{tenant}")
public class FruitResource {
@Inject
EntityManager entityManager;
@GET
@Path("fruits")
public Fruit[] getFruits() {
return entityManager.createNamedQuery("Fruits.findAll", Fruit.class)
.getResultList().toArray(new Fruit[0]);
}
}
Para resolver o tenant a partir das requisições recebidas e mapeá-lo para uma configuração específica de tenant, você precisa criar uma implementação para a interface io.quarkus.hibernate.orm.runtime.tenant.TenantResolver
import javax.enterprise.context.ApplicationScoped;
import io.quarkus.hibernate.orm.runtime.tenant.TenantResolver;
import io.vertx.ext.web.RoutingContext;
@PersistenceUnitExtension (1)
@RequestScoped (2)
public class CustomTenantResolver implements TenantResolver {
@Inject
RoutingContext context;
@Override
public String getDefaultTenantId() {
return "base";
}
@Override
public String resolveTenantId() {
String path = context.request().path();
String[] parts = path.split("/");
if (parts.length == 0) {
// resolve to default tenant config
return getDefaultTenantId();
}
return parts[1];
}
}
| 1 | Anote a implementação do TenantResolver com o qualificador @PersistenceUnitExtension
para informar ao Quarkus que ele deve ser usado na unidade de persistência padrão.
Para unidades de persistência nomeadas, use |
| 2 | O bean é feito @RequestScoped, pois a resolução do tenant depende da requisição recebida. |
Na implementação acima, os tenants são resolvidos a partir do caminho da requisição, de forma que, caso nenhum tenant possa ser inferido, o identificador de tenant padrão é retornado.
|
If you also use OIDC multitenancy and both OIDC and Hibernate ORM tenant IDs are the same and must be extracted from the Vert.x
|
Configurando a aplicação
Em geral, não é possível utilizar o recurso de geração de banco de dados do Hibernate ORM em conjunto com uma configuração de multitenancy. Portanto, você deve desabilitá-lo e garantir que as tabelas sejam criadas por schema. A configuração a seguir utilizará a extensão Flyway para atingir esse objetivo.
Abordagem SCHEMA
The same data source will be used for all tenants and a schema has to be created for every tenant inside that data source. CAUTION: Some databases like MariaDB/MySQL do not support database schemas. In these cases you have to use the DATABASE approach below.
# Disable generation
quarkus.hibernate-orm.database.generation=none
# Enable SCHEMA approach and use default datasource
quarkus.hibernate-orm.multitenant=SCHEMA
# You could use a non-default datasource by using the following setting
# quarkus.hibernate-orm.multitenant-schema-datasource=other
# The default data source used for all tenant schemas
quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=quarkus_test
quarkus.datasource.password=quarkus_test
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/quarkus_test
# Enable Flyway configuration to create schemas
quarkus.flyway.schemas=base,mycompany
quarkus.flyway.locations=classpath:schema
quarkus.flyway.migrate-at-start=true
Aqui está um exemplo do Flyway SQL ( V1.0.0__create_fruits.sql ) a ser criado na pasta configurada src/main/resources/schema.
CREATE SEQUENCE base.known_fruits_id_seq;
SELECT setval('base."known_fruits_id_seq"', 3);
CREATE TABLE base.known_fruits
(
id INT,
name VARCHAR(40)
);
INSERT INTO base.known_fruits(id, name) VALUES (1, 'Cherry');
INSERT INTO base.known_fruits(id, name) VALUES (2, 'Apple');
INSERT INTO base.known_fruits(id, name) VALUES (3, 'Banana');
CREATE SEQUENCE mycompany.known_fruits_id_seq;
SELECT setval('mycompany."known_fruits_id_seq"', 3);
CREATE TABLE mycompany.known_fruits
(
id INT,
name VARCHAR(40)
);
INSERT INTO mycompany.known_fruits(id, name) VALUES (1, 'Avocado');
INSERT INTO mycompany.known_fruits(id, name) VALUES (2, 'Apricots');
INSERT INTO mycompany.known_fruits(id, name) VALUES (3, 'Blackberries');
Abordagem de banco de dados
Para cada tenant, você precisa criar uma fonte de dados nomeada com o mesmo identificador que é retornado pelo TenantResolver.
# Disable generation
quarkus.hibernate-orm.database.generation=none
# Enable DATABASE approach
quarkus.hibernate-orm.multitenant=DATABASE
# Default tenant 'base'
quarkus.datasource.base.db-kind=postgresql
quarkus.datasource.base.username=quarkus_test
quarkus.datasource.base.password=quarkus_test
quarkus.datasource.base.jdbc.url=jdbc:postgresql://localhost:5432/quarkus_test
# Tenant 'mycompany'
quarkus.datasource.mycompany.db-kind=postgresql
quarkus.datasource.mycompany.username=mycompany
quarkus.datasource.mycompany.password=mycompany
quarkus.datasource.mycompany.jdbc.url=jdbc:postgresql://localhost:5433/mycompany
# Flyway configuration for the default datasource
quarkus.flyway.locations=classpath:database/default
quarkus.flyway.migrate-at-start=true
# Flyway configuration for the mycompany datasource
quarkus.flyway.mycompany.locations=classpath:database/mycompany
quarkus.flyway.mycompany.migrate-at-start=true
A seguir, exemplos dos arquivos SQL do Flyway a serem criados na pasta configurada src/main/resources/database.
Default schema (src/main/resources/database/default/V1.0.0__create_fruits.sql):
CREATE SEQUENCE known_fruits_id_seq;
SELECT setval('known_fruits_id_seq', 3);
CREATE TABLE known_fruits
(
id INT,
name VARCHAR(40)
);
INSERT INTO known_fruits(id, name) VALUES (1, 'Cherry');
INSERT INTO known_fruits(id, name) VALUES (2, 'Apple');
INSERT INTO known_fruits(id, name) VALUES (3, 'Banana');
Mycompany schema (src/main/resources/database/mycompany/V1.0.0__create_fruits.sql):
CREATE SEQUENCE known_fruits_id_seq;
SELECT setval('known_fruits_id_seq', 3);
CREATE TABLE known_fruits
(
id INT,
name VARCHAR(40)
);
INSERT INTO known_fruits(id, name) VALUES (1, 'Avocado');
INSERT INTO known_fruits(id, name) VALUES (2, 'Apricots');
INSERT INTO known_fruits(id, name) VALUES (3, 'Blackberries');
Resolução programática de conexões de tenants
Se precisar de uma configuração mais dinâmica para os diferentes locatários que deseja suportar e não quiser ter várias entradas no arquivo de configuração,
poderá usar a interface io.quarkus.hibernate.orm.runtime.tenant.TenantConnectionResolver para implementar sua própria lógica para recuperar uma conexão.
Criar um bean com escopo de aplicativo que implemente essa interface
e anotá-lo com @PersistenceUnitExtension (ou @PersistenceUnitExtension("nameOfYourPU") para uma unidade de persistência nomeada)
substituirá a implementação padrão atual do Quarkus, io.quarkus.hibernate.orm.runtime.tenant.DataSourceTenantConnectionResolver.
Seu resolvedor de conexão personalizado permitiria, por exemplo, ler as informações do locatário de um banco de dados e criar uma conexão por locatário em tempo de execução com base nelas.
Interceptadores
You can assign an org.hibernate.Interceptor
to your SessionFactory by simply defining a CDI bean with the appropriate qualifier:
@PersistenceUnitExtension (1)
public static class MyInterceptor extends EmptyInterceptor { (2)
@Override
public boolean onLoad(Object entity, Serializable id, Object[] state, (3)
String[] propertyNames, Type[] types) {
// ...
return false;
}
}
| 1 | Anote a implementação do interceptador com o qualificador @PersistenceUnitExtension
para informar ao Quarkus que ele deve ser usado na unidade de persistência padrão.
Para unidades de persistência nomeadas, use |
| 2 | Either extend org.hibernate.EmptyInterceptor or implement org.hibernate.Interceptor directly. |
| 3 | Implement methods as necessary. |
|
Por padrão, os beans de interceptador anotados com Para criar uma instância de interceptador por gerente de entidade,
anote seu bean com |
|
Devido a uma limitação do próprio Hibernate ORM,
os métodos |