Documentation updates for JPA 3.2
Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
b1135b537c
commit
b7dc7292ca
|
@ -4,7 +4,7 @@
|
|||
We would love to make this section short.
|
||||
Unfortunately, there are several distinct ways to configure and bootstrap Hibernate, and we're going to have to describe at least two of them in detail.
|
||||
|
||||
The four basic ways to obtain an instance of Hibernate are shown in the following table:
|
||||
The five basic ways to obtain an instance of Hibernate are shown in the following table:
|
||||
|
||||
[%breakable,cols="50,50",number=0]
|
||||
|===
|
||||
|
@ -12,8 +12,11 @@ The four basic ways to obtain an instance of Hibernate are shown in the followin
|
|||
| Using the standard JPA-defined XML, and the operation `Persistence.createEntityManagerFactory()`
|
||||
| Usually chosen when portability between JPA implementations is important.
|
||||
|
||||
| Using the link:{doc-javadoc-url}org/hibernate/cfg/Configuration.html[`Configuration`] class to construct a `SessionFactory`
|
||||
| When portability between JPA implementations is not important, this option is quicker, adds some flexibility and saves a typecast.
|
||||
| Using the standard JPA-defined `PersistenceConfiguration` class
|
||||
| Usually chosen when portability between JPA implementations is important, but programmatic control is desired.
|
||||
|
||||
| Using link:{doc-javadoc-url}org/hibernate/jpa/HibernatePersistenceConfiguration.html[`HibernatePersistenceConfiguration`] or the older link:{doc-javadoc-url}org/hibernate/cfg/Configuration.html[`Configuration`] class to construct a `SessionFactory`
|
||||
| When portability between JPA implementations is not important, this option adds some convenience and saves a typecast.
|
||||
|
||||
| Using the more complex APIs defined in link:{doc-javadoc-url}org/hibernate/boot/package-summary.html[`org.hibernate.boot`]
|
||||
| Used primarily by framework integrators, this option is outside the scope of this document.
|
||||
|
@ -102,7 +105,7 @@ or `org.slf4j:slf4j-jdk14`
|
|||
| A JDBC connection pool, for example, {agroal}[Agroal] |
|
||||
`org.hibernate.orm:hibernate-agroal` +
|
||||
and `io.agroal:agroal-pool`
|
||||
| The {generator}[Hibernate Metamodel Generator], especially if you're using the JPA criteria query API | `org.hibernate.orm:hibernate-processor`
|
||||
| The {generator}[Hibernate Processor], especially if you're using Jakarta Data or the JPA criteria query API | `org.hibernate.orm:hibernate-processor`
|
||||
| The {query-validator}[Query Validator], for compile-time checking of HQL | `org.hibernate:query-validator`
|
||||
| {validator}[Hibernate Validator], an implementation of {bean-validation}[Bean Validation] |
|
||||
`org.hibernate.validator:hibernate-validator` +
|
||||
|
@ -202,41 +205,54 @@ EntityManagerFactory entityManagerFactory =
|
|||
----
|
||||
|
||||
[[configuration-api]]
|
||||
=== Configuration using Hibernate API
|
||||
=== Programmatic configuration using JPA API
|
||||
|
||||
Alternatively, the venerable class link:{doc-javadoc-url}org/hibernate/cfg/Configuration.html[`Configuration`] allows an instance of Hibernate to be configured in Java code.
|
||||
The new `PersistenceConfiguration` class allows full programmatic control over creation of the `EntityManagerFactory`.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
EntityManagerFactory entityManagerFactory =
|
||||
new PersistenceConfiguration("Bookshop")
|
||||
.managedClass(Book.class)
|
||||
.managedClass(Author.class)
|
||||
// PostgreSQL
|
||||
.property(PersistenceConfiguration.JDBC_URL, "jdbc:postgresql://localhost/example")
|
||||
// Credentials
|
||||
.property(PersistenceConfiguration.JDBC_USER, user)
|
||||
.property(PersistenceConfiguration.JDBC_PASSWORD, password)
|
||||
// Automatic schema export
|
||||
.property(PersistenceConfiguration.SCHEMAGEN_DATABASE_ACTION,
|
||||
Action.SPEC_ACTION_DROP_AND_CREATE)
|
||||
// SQL statement logging
|
||||
.property(JdbcSettings.SHOW_SQL, true)
|
||||
.property(JdbcSettings.FORMAT_SQL, true)
|
||||
.property(JdbcSettings.HIGHLIGHT_SQL, true)
|
||||
// Create a new EntityManagerFactory
|
||||
.createEntityManagerFactory();
|
||||
----
|
||||
|
||||
The specification gives JPA implementors like Hibernate explicit permission to extend this class, and so Hibernate offers the link:{doc-javadoc-url}org/hibernate/jpa/HibernatePersistenceConfiguration.html[`HibernatePersistenceConfiguration`], which lets us obtain a `SessionFactory` without any need for a cast.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
SessionFactory sessionFactory =
|
||||
new Configuration()
|
||||
.addAnnotatedClass(Book.class)
|
||||
.addAnnotatedClass(Author.class)
|
||||
// PostgreSQL
|
||||
.setProperty(AvailableSettings.JAKARTA_JDBC_URL, "jdbc:postgresql://localhost/example")
|
||||
// Credentials
|
||||
.setProperty(AvailableSettings.JAKARTA_JDBC_USER, user)
|
||||
.setProperty(AvailableSettings.JAKARTA_JDBC_PASSWORD, password)
|
||||
// Automatic schema export
|
||||
.setProperty(AvailableSettings.JAKARTA_HBM2DDL_DATABASE_ACTION,
|
||||
Action.SPEC_ACTION_DROP_AND_CREATE)
|
||||
// SQL statement logging
|
||||
.setProperty(AvailableSettings.SHOW_SQL, true)
|
||||
.setProperty(AvailableSettings.FORMAT_SQL, true)
|
||||
.setProperty(AvailableSettings.HIGHLIGHT_SQL, true)
|
||||
new HibernatePersistenceConfiguration("Bookshop")
|
||||
.managedClass(Book.class)
|
||||
.managedClass(Author.class)
|
||||
// Set properties
|
||||
...
|
||||
// Create a new SessionFactory
|
||||
.buildSessionFactory();
|
||||
.createEntityManagerFactory();
|
||||
----
|
||||
|
||||
The `Configuration` class has survived almost unchanged since the very earliest (pre-1.0) versions of Hibernate, and so it doesn't look particularly modern.
|
||||
On the other hand, it's very easy to use, and exposes some options that `persistence.xml` doesn't support.
|
||||
Alternatively, the venerable class link:{doc-javadoc-url}org/hibernate/cfg/Configuration.html[`Configuration`] offers similar functionality.
|
||||
|
||||
:native-bootstrap: {doc-user-guide-url}#bootstrap-native
|
||||
:boot: {doc-javadoc-url}/org/hibernate/boot/package-summary.html
|
||||
|
||||
.Advanced configuration options
|
||||
****
|
||||
Actually, the `Configuration` class is just a very simple facade for the more modern, much more powerful—but more complex—API defined in the package `org.hibernate.boot`.
|
||||
Actually, these APIs are very simple facades resting on the much more powerful--but also more complex--APIs defined in the package `org.hibernate.boot`.
|
||||
This API is useful if you have very advanced requirements, for example, if you're writing a framework or implementing a container.
|
||||
You'll find more information in the {native-bootstrap}[User Guide], and in the {boot}[package-level documentation] of `org.hibernate.boot`.
|
||||
****
|
||||
|
@ -244,7 +260,7 @@ You'll find more information in the {native-bootstrap}[User Guide], and in the {
|
|||
[[configuration-properties]]
|
||||
=== Configuration using Hibernate properties file
|
||||
|
||||
If we're using the Hibernate `Configuration` API, but we don't want to put certain configuration properties directly in the Java code, we can specify them in a file named `hibernate.properties`, and place the file in the root classpath.
|
||||
If we're using programmatic configuration, but we don't want to put certain configuration properties directly in the Java code, we can specify them in a file named `hibernate.properties`, and place the file in the root classpath.
|
||||
|
||||
[source,properties]
|
||||
----
|
||||
|
@ -263,7 +279,9 @@ hibernate.highlight_sql=true
|
|||
[[basic-configuration-settings]]
|
||||
=== Basic configuration settings
|
||||
|
||||
The class link:{doc-javadoc-url}org/hibernate/cfg/AvailableSettings.html[`AvailableSettings`] enumerates all the configuration properties understood by Hibernate.
|
||||
The `PersistenceConfiguration` class declares `static final` constants holding the names of all configuration properties defined by the specification itself, for example, `JDBC_URL` holds the property name `"jakarta.persistence.jdbc.driver"`.
|
||||
|
||||
Similarly, the class link:{doc-javadoc-url}org/hibernate/cfg/AvailableSettings.html[`AvailableSettings`] enumerates all the configuration properties understood by Hibernate.
|
||||
|
||||
Of course, we're not going to cover every useful configuration setting in this chapter.
|
||||
Instead, we'll mention the ones you need to get started, and come back to some other important settings later, especially when we talk about performance tuning.
|
||||
|
@ -408,13 +426,7 @@ As we mentioned <<testing,earlier>>, it can also be useful to control schema exp
|
|||
The link:{doc-javadoc-url}org/hibernate/relational/SchemaManager.html[`SchemaManager`] API allows programmatic control over schema export:
|
||||
|
||||
[source,java]
|
||||
sessionFactory.getSchemaManager().exportMappedObjects(true);
|
||||
|
||||
JPA has a more limited and less ergonomic API:
|
||||
|
||||
[source,java]
|
||||
Persistence.generateSchema("org.hibernate.example",
|
||||
Map.of(JAKARTA_HBM2DDL_DATABASE_ACTION, CREATE))
|
||||
sessionFactory.getSchemaManager().export(true);
|
||||
====
|
||||
|
||||
[[logging-generated-sql]]
|
||||
|
|
|
@ -497,7 +497,7 @@ The JPA specification defines a quite limited set of basic types:
|
|||
| Primitive wrappers | `java.lang` | `Boolean`, `Integer`, `Double`, etc
|
||||
| Strings | `java.lang` | `String`
|
||||
| Arbitrary-precision numeric types | `java.math` | `BigInteger`, `BigDecimal`
|
||||
| Date/time types | `java.time` | `LocalDate`, `LocalTime`, `LocalDateTime`, `OffsetDateTime`, `Instant`
|
||||
| Date/time types | `java.time` | `LocalDate`, `LocalTime`, `LocalDateTime`, `OffsetDateTime`, `Instant`, `Year`
|
||||
| Deprecated date/time types 💀 | `java.util` | `Date`, `Calendar`
|
||||
| Deprecated JDBC date/time types 💀 | `java.sql` | `Date`, `Time`, `Timestamp`
|
||||
| Binary and character arrays | | `byte[]`, `char[]`
|
||||
|
@ -600,7 +600,23 @@ Status status;
|
|||
|
||||
----
|
||||
|
||||
In Hibernate 6, an `enum` annotated `@Enumerated(STRING)` is mapped to:
|
||||
The `@EnumeratedValue` annotation allows the column value to be customized:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
enum Resolution {
|
||||
UNRESOLVED(0), FIXED(1), REJECTED(-1);
|
||||
|
||||
@EnumeratedValue // store the code, not the enum ordinal() value
|
||||
final int code;
|
||||
|
||||
Resolution(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
Since Hibernate 6, an `enum` annotated `@Enumerated(STRING)` is mapped to:
|
||||
|
||||
- a `VARCHAR` column type with a `CHECK` constraint on most databases, or
|
||||
- an `ENUM` column type on MySQL.
|
||||
|
|
|
@ -625,11 +625,11 @@ configuration.setProperty(AvailableSettings.JAKARTA_HBM2DDL_DATABASE_ACTION,
|
|||
Action.SPEC_ACTION_DROP_AND_CREATE);
|
||||
----
|
||||
|
||||
Alternatively, in Hibernate 6, we may use the new link:{doc-javadoc-url}org/hibernate/relational/SchemaManager.html[`SchemaManager`] API to export the schema, just as we did <<main-hibernate,above>>.
|
||||
Alternatively, we may use the new link:{doc-javadoc-url}org/hibernate/relational/SchemaManager.html[`SchemaManager`] API to export the schema, just as we did <<main-hibernate,above>>.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
sessionFactory.getSchemaManager().exportMappedObjects(true);
|
||||
sessionFactory.getSchemaManager().export(true);
|
||||
----
|
||||
|
||||
Since executing DDL statements is very slow on many databases, we don't want to do this before every test.
|
||||
|
@ -642,7 +642,7 @@ We may truncate all the tables, leaving an empty database schema, using the `Sch
|
|||
|
||||
[source,java]
|
||||
----
|
||||
sessionFactory.getSchemaManager().truncateMappedObjects();
|
||||
sessionFactory.getSchemaManager().truncate();
|
||||
----
|
||||
|
||||
After truncating tables, we might need to initialize our test data.
|
||||
|
@ -668,7 +668,7 @@ configuration.setProperty(AvailableSettings.JAKARTA_HBM2DDL_LOAD_SCRIPT_SOURCE,
|
|||
"/org/example/test-data.sql");
|
||||
----
|
||||
|
||||
The SQL script will be executed every time `exportMappedObjects()` or `truncateMappedObjects()` is called.
|
||||
The SQL script will be executed every time `export()` or `truncate()` is called.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Given a domain model—that is, a collection of entity classes decorated with all the fancy annotations we <<entities-summary,just met>> in the previous chapter—Hibernate will happily go away and infer a complete relational schema, and even <<automatic-schema-export,export it to your database>> if you ask politely.
|
||||
|
||||
The resulting schema will be entirely sane and reasonable, though if you look closely, you'll find some flaws.
|
||||
For example, every `VARCHAR` column will have the same length, `VARCHAR(255)`.
|
||||
For example, by default, every `VARCHAR` column will have the same length, `VARCHAR(255)`.
|
||||
|
||||
But the process I just described—which we call _top down_ mapping—simply doesn't fit the most common scenario for the use of O/R mapping.
|
||||
It's only rarely that the Java classes precede the relational schema.
|
||||
|
@ -220,6 +220,8 @@ The `@Table` annotation can do more than just specify a name:
|
|||
| `catalog` 💀 | The catalog to which the table belongs
|
||||
| `uniqueConstraints` | One or more `@UniqueConstraint` annotations declaring multi-column unique constraints
|
||||
| `indexes` | One or more `@Index` annotations each declaring an index
|
||||
| `check` | One or more `@CheckConstraint` annotations declaring multi-column check constraints
|
||||
| `comment` | A DDL comment
|
||||
|===
|
||||
|
||||
[%unbreakable]
|
||||
|
@ -249,6 +251,8 @@ The `@SecondaryTable` annotation is even more interesting:
|
|||
| `indexes` | One or more `@Index` annotations each declaring an index
|
||||
| `pkJoinColumns` | One or more `@PrimaryKeyJoinColumn` annotations, specifying <<primary-key-column-mappings,primary key column mappings>>
|
||||
| `foreignKey` | A `@ForeignKey` annotation specifying the name of the `FOREIGN KEY` constraint on the ``@PrimaryKeyJoinColumn``s
|
||||
| `check` | One or more `@CheckConstraint` annotations declaring multi-column check constraints
|
||||
| `comment` | A DDL comment
|
||||
|===
|
||||
|
||||
[TIP]
|
||||
|
@ -324,6 +328,8 @@ Here, there should be a `UNIQUE` constraint on _both_ columns of the association
|
|||
| `inverseJoinColumns` | One or more `@JoinColumn` annotations, specifying <<join-column-mappings,foreign key column mappings>> to the table of the unowned side
|
||||
| `foreignKey` | A `@ForeignKey` annotation specifying the name of the `FOREIGN KEY` constraint on the ``joinColumns``s
|
||||
| `inverseForeignKey` | A `@ForeignKey` annotation specifying the name of the `FOREIGN KEY` constraint on the ``inverseJoinColumns``s
|
||||
| `check` | One or more `@CheckConstraint` annotations declaring multi-column check constraints
|
||||
| `comment` | A DDL comment
|
||||
|===
|
||||
|
||||
To better understand these annotations, we must first discuss column mappings in general.
|
||||
|
@ -360,13 +366,16 @@ The `@Column` annotation is not only useful for specifying the column name.
|
|||
| `name` | The name of the mapped column
|
||||
| `table` | The name of the table to which this column belongs
|
||||
| `length` | The length of a `VARCHAR`, `CHAR`, or `VARBINARY` column type
|
||||
| `precision` | The decimal digits of precision of a `FLOAT`, `DECIMAL`, `NUMERIC`, or `TIME`, or `TIMESTAMP` column type
|
||||
| `precision` | The decimal digits of precision of a `FLOAT`, `DECIMAL`, or `NUMERIC` type
|
||||
| `scale` | The scale of a `DECIMAL` or `NUMERIC` column type, the digits of precision that occur to the right of the decimal point
|
||||
| `secondPrecision` | The digits of precision occurring to the right of the decimal point in the seconds field of a `TIME`, or `TIMESTAMP` column type
|
||||
| `unique` | Whether the column has a `UNIQUE` constraint
|
||||
| `nullable` | Whether the column has a `NOT NULL` constraint
|
||||
| `insertable` | Whether the column should appear in generated SQL `INSERT` statements
|
||||
| `updatable` | Whether the column should appear in generated SQL `UPDATE` statements
|
||||
| `columnDefinition` 💀| A DDL fragment that should be used to declare the column
|
||||
| `check` | One or more `@CheckConstraint` annotations declaring single-column check constraints
|
||||
| `comment` | A DDL comment
|
||||
|===
|
||||
|
||||
[TIP]
|
||||
|
@ -420,6 +429,8 @@ The `@JoinColumn` annotation is used to customize a foreign key column.
|
|||
| `updatable` | Whether the column should appear in generated SQL `UPDATE` statements
|
||||
| `columnDefinition` 💀| A DDL fragment that should be used to declare the column
|
||||
| `foreignKey` | A `@ForeignKey` annotation specifying the name of the `FOREIGN KEY` constraint
|
||||
| `check` | One or more `@CheckConstraint` annotations declaring single-column check constraints
|
||||
| `comment` | A DDL comment
|
||||
|===
|
||||
|
||||
A foreign key column doesn't necessarily have to refer to the primary key of the referenced table.
|
||||
|
@ -593,7 +604,7 @@ class Book {
|
|||
=== Column lengths and adaptive column types
|
||||
|
||||
Hibernate automatically adjusts the column type used in generated DDL based on the column length specified by the `@Column` annotation.
|
||||
So we don't usually need to explicitly specify that a column should be of type `TEXT` or `CLOB`—or worry about the parade of `TINYTEXT`, `MEDIUMTEXT`, `TEXT`, `LONGTEXT` types on MySQL—because Hibernate will automatically select one of those types if required to accommodate a string of the `length` we specify.
|
||||
So we don't usually need to explicitly specify that a column should be of type `TEXT` or `CLOB`—or worry about the parade of `TINYTEXT`, `MEDIUMTEXT`, `TEXT`, `LONGTEXT` types on MySQL—because Hibernate automatically selects one of those types if required to accommodate a string of the `length` we specify.
|
||||
|
||||
The constant values defined in the class link:{doc-javadoc-url}org/hibernate/Length.html[`Length`] are very helpful here:
|
||||
|
||||
|
@ -805,7 +816,7 @@ Here we summarize the ones we've just seen in the second half of this chapter, a
|
|||
|===
|
||||
| Annotation | Interpretation
|
||||
|
||||
| `@Enumerated` | Specify how an `enum` type should be persisted
|
||||
| `@Enumerated`, `@EnumeratedValue` | Specify how an `enum` type should be persisted
|
||||
| `@Nationalized` | Use a nationalized character type: `NCHAR`, `NVARCHAR`, or `NCLOB`
|
||||
| `@Lob` 💀 | Use JDBC LOB APIs to read and write the annotated attribute
|
||||
| `@Array` | Map a collection to a SQL `ARRAY` type of the specified length
|
||||
|
@ -828,6 +839,7 @@ In addition, there are some configuration properties which have a _global_ affec
|
|||
| `hibernate.type.preferred_duration_jdbc_type` | Specify the default SQL column type for mapping `Duration`
|
||||
| `hibernate.type.preferred_instant_jdbc_type` | Specify the default SQL column type for mapping `Instant`
|
||||
| `hibernate.timezone.default_storage` | Specify the default strategy for storing time zone information
|
||||
| `` |
|
||||
|===
|
||||
|
||||
[TIP]
|
||||
|
|
Loading…
Reference in New Issue