Examples
Example#1
- On basis https://how-to.vertx.io/hibernate-reactive-howto/
- Db: PostgreSQL
- Db tests: https://java.testcontainers.org/modules/databases/postgres/
Product.java
package zjc.examples.vertx.hibernate;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import java.math.BigDecimal;
@Entity
public class Product {
@Id
@GeneratedValue
private Long id;
@Column(unique = true)
private String name;
@Column(nullable = false)
private BigDecimal price;
public Product() {
}
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 BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
}
MainVerticle.java
package zjc.examples.vertx.hibernate;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.vertx.core.AbstractVerticle;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.json.JsonObject;
import io.vertx.mutiny.core.Vertx;
import io.vertx.mutiny.core.http.HttpServer;
import io.vertx.mutiny.ext.web.Router;
import io.vertx.mutiny.ext.web.RoutingContext;
import io.vertx.mutiny.ext.web.handler.BodyHandler;
import org.hibernate.reactive.mutiny.Mutiny;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testcontainers.containers.PostgreSQLContainer;
import javax.persistence.Persistence;
import java.util.List;
import java.util.Map;
// tag::preamble[]
public class MainVerticle extends AbstractVerticle {
private static final Logger logger = LoggerFactory.getLogger(MainVerticle.class);
private Mutiny.SessionFactory emf; // <1>D
@Override
public Uni<Void> asyncStart() {
// end::preamble[]
// tag::hr-start[]
Uni<Void> startHibernate = Uni.createFrom().deferred(() -> {
var pgPort = config().getInteger("pgPort", 5432);
var props = Map.of("javax.persistence.jdbc.url", "jdbc:postgresql://localhost:" + pgPort + "/postgres"); // <1>
emf = Persistence
.createEntityManagerFactory("pg-demo", props)
.unwrap(Mutiny.SessionFactory.class);
return Uni.createFrom().voidItem();
});
startHibernate = vertx.executeBlocking(startHibernate) // <2>
.onItem().invoke(() -> logger.info("✅ Hibernate Reactive is ready"));
// end::hr-start[]
// tag::routing[]
Router router = Router.router(vertx);
BodyHandler bodyHandler = BodyHandler.create();
router.post().handler(bodyHandler::handle);
router.get("/products").respond(this::listProducts);
router.get("/products/:id").respond(this::getProduct);
router.post("/products").respond(this::createProduct);
// end::routing[]
// tag::async-start[]
Uni<HttpServer> startHttpServer = vertx.createHttpServer()
.requestHandler(router)
.listen(8080)
.onItem().invoke(() -> logger.info("✅ HTTP server listening on port 8080"));
return Uni.combine().all().unis(startHibernate, startHttpServer).discardItems(); // <1>
// end::async-start[]
}
// tag::crud-methods[]
private Uni<List<Product>> listProducts(RoutingContext ctx) {
return emf.withSession(session -> session
.createQuery("from Product", Product.class)
.getResultList());
}
private Uni<Product> getProduct(RoutingContext ctx) {
long id = Long.parseLong(ctx.pathParam("id"));
return emf.withSession(session -> session
.find(Product.class, id))
.onItem().ifNull().continueWith(Product::new);
}
private Uni<Product> createProduct(RoutingContext ctx) {
Product product = ctx.body().asPojo(Product.class);
return emf.withSession(session -> session.
persist(product)
.call(session::flush)
.replaceWith(product));
}
// end::crud-methods[]
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
logger.info("🚀 Starting a PostgreSQL container");
// tag::tc-start[]
PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>("postgres:11-alpine")
.withDatabaseName("postgres")
.withUsername("postgres")
.withPassword("vertx-in-action");
postgreSQLContainer.start();
// end::tc-start[]
long tcTime = System.currentTimeMillis();
logger.info("🚀 Starting Vert.x");
// tag::vertx-start[]
Vertx vertx = Vertx.vertx();
DeploymentOptions options = new DeploymentOptions().setConfig(new JsonObject()
.put("pgPort", postgreSQLContainer.getMappedPort(5432))); // <1>
vertx.deployVerticle(MainVerticle::new, options).subscribe().with( // <2>
ok -> {
long vertxTime = System.currentTimeMillis();
logger.info("✅ Deployment success");
logger.info("💡 PostgreSQL container started in {}ms", (tcTime - startTime));
logger.info("💡 Vert.x app started in {}ms", (vertxTime - tcTime));
},
err -> logger.error("🔥 Deployment failure", err));
// end::vertx-start[]
}
}
Complete code: http://jreact.com/index.php/2023/12/12/vertx-hibernate-example-01/
Example#2
- Vert.x
- PostgreSQL
- Hibernate reactive
- REST
- Flyway
Running
mvn compile exec:java
[INFO] Scanning for projects...
[INFO]
[INFO] --------------< zjc.examples:vertx-hibernate-example-02 >---------------
[INFO] Building vertx-hibernate-example-02 1.0.0-SNAPSHOT
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ vertx-hibernate-example-02 ---
[INFO] Copying 4 resources from src/main/resources to target/classes
[INFO]
[INFO] --- compiler:3.10.1:compile (default-compile) @ vertx-hibernate-example-02 ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 7 source files to /home/zbyszek/IdeaProjects/reactive/github/zjc-examples/vertx/hibernate/vertx-hibernate-example-02/target/classes
[INFO] /home/zbyszek/IdeaProjects/reactive/github/zjc-examples/vertx/hibernate/vertx-hibernate-example-02/src/main/java/zjc/examples/vertx/hibernate/utils/DbUtils.java: /home/zbyszek/IdeaProjects/reactive/github/zjc-examples/vertx/hibernate/vertx-hibernate-example-02/src/main/java/zjc/examples/vertx/hibernate/utils/DbUtils.java uses or overrides a deprecated API.
[INFO] /home/zbyszek/IdeaProjects/reactive/github/zjc-examples/vertx/hibernate/vertx-hibernate-example-02/src/main/java/zjc/examples/vertx/hibernate/utils/DbUtils.java: Recompile with -Xlint:deprecation for details.
[INFO]
[INFO] --- exec:3.0.0:java (default-cli) @ vertx-hibernate-example-02 ---
2023-12-14 16:21:26,827 INFO [zjc.examples.vertx.hibernate.MainVerticle.main()] zjc.examples.vertx.hibernate.MainVerticle - 🚀 Starting a PostgreSQL
2023-12-14 16:21:27,038 INFO [zjc.examples.vertx.hibernate.MainVerticle.main()] zjc.examples.vertx.hibernate.MainVerticle - 🚀 Starting Vert.x
2023-12-14 16:21:27,121 INFO [vert.x-eventloop-thread-0] org.flywaydb.core.internal.license.VersionPrinter - Flyway Community Edition 9.0.2 by Redgate
2023-12-14 16:21:27,121 INFO [vert.x-eventloop-thread-0] org.flywaydb.core.internal.license.VersionPrinter - See what's new here: https://flywaydb.org/documentation/learnmore/releaseNotes#9.0.2
2023-12-14 16:21:27,121 INFO [vert.x-eventloop-thread-0] org.flywaydb.core.internal.license.VersionPrinter -
2023-12-14 16:21:27,123 DEBUG [vert.x-eventloop-thread-0] org.flywaydb.core.internal.util.FeatureDetector - AWS SDK available: false
2023-12-14 16:21:27,123 DEBUG [vert.x-eventloop-thread-0] org.flywaydb.core.internal.util.FeatureDetector - Google Cloud Storage available: false
2023-12-14 16:21:27,124 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.scanner.classpath.ClassPathScanner - Multiple databases found that handle url 'jdbc:postgresql://localhost:5432/vertx-rest': CockroachDB, PostgreSQL
2023-12-14 16:21:27,124 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.scanner.classpath.ClassPathScanner - Scanning for classpath resources at 'classpath:db/callback' ...
2023-12-14 16:21:27,124 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.scanner.classpath.ClassPathScanner - Determining location urls for classpath:db/callback using ClassLoader java.net.URLClassLoader@537ca28e ...
2023-12-14 16:21:27,124 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.scanner.classpath.ClassPathScanner - Unable to resolve location classpath:db/callback.
2023-12-14 16:21:27,124 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.scanner.classpath.ClassPathScanner - Scanning for classpath resources at 'classpath:db/migration' ...
2023-12-14 16:21:27,124 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.scanner.classpath.ClassPathScanner - Determining location urls for classpath:db/migration using ClassLoader java.net.URLClassLoader@537ca28e ...
2023-12-14 16:21:27,125 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.scanner.classpath.ClassPathScanner - Scanning URL: file:/home/zbyszek/IdeaProjects/reactive/github/zjc-examples/vertx/hibernate/vertx-hibernate-example-02/target/classes/db/migration
2023-12-14 16:21:27,125 DEBUG [vert.x-eventloop-thread-0] org.flywaydb.core.internal.util.FeatureDetector - JBoss VFS v2 available: false
2023-12-14 16:21:27,126 DEBUG [vert.x-eventloop-thread-0] o.f.c.i.s.c.FileSystemClassPathLocationScanner - Scanning starting at classpath root in filesystem: /home/zbyszek/IdeaProjects/reactive/github/zjc-examples/vertx/hibernate/vertx-hibernate-example-02/target/classes/
2023-12-14 16:21:27,126 DEBUG [vert.x-eventloop-thread-0] o.f.c.i.s.c.FileSystemClassPathLocationScanner - Scanning for resources in path: /home/zbyszek/IdeaProjects/reactive/github/zjc-examples/vertx/hibernate/vertx-hibernate-example-02/target/classes/db/migration (db/migration)
2023-12-14 16:21:27,128 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.scanner.classpath.ClassPathScanner - Found resource: db/migration/V0.1__create_product_table.sql
2023-12-14 16:21:27,128 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.scanner.classpath.ClassPathScanner - Scanning for classes at classpath:db/migration
2023-12-14 16:21:27,132 DEBUG [vert.x-eventloop-thread-0] o.f.core.internal.resource.ResourceNameValidator - Validating V0.1__create_product_table.sql
2023-12-14 16:21:27,222 INFO [vert.x-eventloop-thread-0] zjc.examples.vertx.hibernate.MainVerticle - ✅ HTTP server listening on port 8080
2023-12-14 16:21:27,266 INFO [vert.x-worker-thread-0] org.hibernate.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: pg-demo]
2023-12-14 16:21:27,322 INFO [vert.x-worker-thread-0] org.hibernate.Version - HHH000412: Hibernate ORM core version 5.6.12.Final
2023-12-14 16:21:27,507 INFO [vert.x-worker-thread-0] org.hibernate.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
2023-12-14 16:21:27,571 INFO [vert.x-eventloop-thread-0] o.f.core.internal.database.base.BaseDatabaseType - Database: jdbc:postgresql://localhost:5432/vertx-rest (PostgreSQL 14.9)
2023-12-14 16:21:27,572 DEBUG [vert.x-eventloop-thread-0] o.f.core.internal.database.base.BaseDatabaseType - Driver : PostgreSQL JDBC Driver 42.2.18
2023-12-14 16:21:27,575 DEBUG [vert.x-eventloop-thread-0] org.flywaydb.core.FlywayExecutor - DDL Transactions Supported: true
2023-12-14 16:21:27,577 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.schemahistory.SchemaHistoryFactory - Schemas:
2023-12-14 16:21:27,577 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.schemahistory.SchemaHistoryFactory - Default schema: null
2023-12-14 16:21:27,589 DEBUG [vert.x-eventloop-thread-0] o.f.c.internal.callback.SqlScriptCallbackFactory - Scanning for SQL callbacks ...
2023-12-14 16:21:27,598 DEBUG [vert.x-eventloop-thread-0] org.flywaydb.core.internal.command.DbValidate - Validating migrations ...
2023-12-14 16:21:27,611 DEBUG [vert.x-eventloop-thread-0] org.flywaydb.core.internal.scanner.Scanner - Filtering out resource: db/migration/V0.1__create_product_table.sql (filename: V0.1__create_product_table.sql)
2023-12-14 16:21:27,637 DEBUG [vert.x-eventloop-thread-0] org.flywaydb.core.FlywayExecutor - Memory usage: 73 of 138M
2023-12-14 16:21:27,681 INFO [vert.x-worker-thread-0] org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL10Dialect
2023-12-14 16:21:27,910 INFO [vert.x-worker-thread-0] o.h.reactive.provider.impl.ReactiveIntegrator - HR000001: Hibernate Reactive
2023-12-14 16:21:28,299 INFO [vert.x-worker-thread-0] o.h.reactive.pool.impl.DefaultSqlClientPool - HR000011: SQL Client URL [jdbc:postgresql://localhost:5432/vertx-rest]
2023-12-14 16:21:28,304 INFO [vert.x-worker-thread-0] o.h.r.pool.impl.DefaultSqlClientPoolConfiguration - HR000025: Connection pool size: 10
[Hibernate]
select
*
from
information_schema.sequences
[Hibernate]
select
table_catalog as table_cat ,
table_schema as table_schem ,
table_name as table_name ,
table_type as table_type ,
null as remarks
from
information_schema.tables
where
1 = 1
and table_name like $1
and table_type in (
$2, $3, $4, $5
)
[Hibernate]
select
table_name as table_name,
column_name as column_name,
case
when udt_name = 'bpchar' then 'CHAR'
else udt_name
end as type_name,
null as column_size,
null as decimal_digits,
is_nullable as is_nullable,
null as data_type
from
information_schema.columns
where
1 = 1
order by
table_catalog,
table_schema,
table_name,
column_name,
ordinal_position
2023-12-14 16:21:28,655 INFO [vert.x-eventloop-thread-0] zjc.examples.vertx.hibernate.MainVerticle - ✅ Hibernate Reactive is ready
2023-12-14 16:21:28,657 INFO [vert.x-eventloop-thread-1] zjc.examples.vertx.hibernate.MainVerticle - ✅ Deployment success
2023-12-14 16:21:28,657 INFO [vert.x-eventloop-thread-1] zjc.examples.vertx.hibernate.MainVerticle - 💡 PostgreSQL started in 211ms
2023-12-14 16:21:28,657 INFO [vert.x-eventloop-thread-1] zjc.examples.vertx.hibernate.MainVerticle - 💡 Vert.x app started in 1619ms
Complete code: http://jreact.com/index.php/2023/12/14/vertx-hibernate-example-02/
Example#3
- Vert.x
- io.vertx.mutiny.ext.web.Router
- Mutiny.SessionFactory emf;
- SessionFactory factory;
- REST
- Hibernate Reactive
- One to Many relationship
- PostgreSQL
