Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
181 commits
Select commit Hold shift + click to select a range
7c61e20
update to latest asciidoc theme
gavinking Nov 25, 2025
79d98c2
more refactoring to ModelBinder
gavinking Nov 25, 2025
6eba60e
even more refactoring to ModelBinder
gavinking Nov 26, 2025
b78f80f
HHH-19843 Get persister from session factory if session is not available
marko-bekhta Oct 6, 2025
e41bb02
Change how release_notes are discovered
marko-bekhta Nov 25, 2025
e709838
HHH-19958 Implement the custom orm.xml `<generated>` tag
bjansen Nov 26, 2025
72dae39
HHH-18871 allow collections to be mapped correctly while determining …
robwgreenjr Oct 12, 2025
2269a00
HHH-19215 handle queries with straight_join or just order by
hogeunchung Mar 1, 2025
c1d4760
HHH-19725 Test upsert for entity type that only declares an ID attribute
yrodiere Aug 20, 2025
eacb836
HHH-18217 Properly handle empty value bindings for merge operations
beikov Aug 28, 2025
6cfdc64
HHH-19963 Only consider a ToOne be bidirectional for OneToMany if FKs…
beikov Nov 28, 2025
76d6228
clean up some uses of BOOT_LOGGER
gavinking Dec 1, 2025
7ffcd4f
miscellaneous minor code cleanups
gavinking Dec 1, 2025
d100907
add item to SchemaManager jdoc
gavinking Dec 1, 2025
8631bb2
HHH-19965 remove misleading examples from the User Guide
gavinking Dec 2, 2025
eb898b1
HHH-19926 add tests
gavinking Nov 13, 2025
fee7ed7
minor cleanups to BeanValidationEventListener
gavinking Dec 3, 2025
9cda810
HHH-19975 validate LoadEvent when it is reused
gavinking Dec 4, 2025
c6820d2
improve some locking-related error messages
gavinking Dec 4, 2025
c3ebcd2
HHH-19977 Relax scopes to allow HR to run a reactive flush
DavideD Dec 4, 2025
b918272
refactoring and cleanup to the procedure.internal package
gavinking Dec 5, 2025
5874eef
fix lots of NPEs in ProcedureParameterMetadataImpl
gavinking Dec 5, 2025
c893708
fix annoying assertions that test error message text
gavinking Dec 5, 2025
333dd4e
just use a loop
gavinking Dec 5, 2025
8213cca
improve jdoc of SS.xxxxMultiple() methods
gavinking Dec 5, 2025
84b3775
HHH-19943 Add test for issue
mbellade Dec 3, 2025
95c7bc6
HHH-19943 Use resolved type for `SqmSelectableNode#getTupeLength`
mbellade Dec 3, 2025
bdcbd99
fill in impl of methods of EntityJavaType
gavinking Dec 5, 2025
b0016bc
remove unnecessary LOG in Table
gavinking Dec 5, 2025
d4b83dd
code cleanups in sql.results.jdbc.internal
gavinking Dec 5, 2025
4330fb7
eliminate some unnecessary overrides in JavaTypes
gavinking Dec 5, 2025
e991a42
fix to code generation for Jakarta Data delete() method
gavinking Dec 5, 2025
ee2fa41
minor aesthetic cleanups to the date/time JavaTypes
gavinking Dec 6, 2025
52c6583
misc cleanups in SessionImpl
gavinking Dec 6, 2025
17eccc3
fix impl of EntityManager.getProperties() to comply with Javadoc
gavinking Dec 6, 2025
ed05cdf
improved explanations of constructor stuff for repositories
gavinking Dec 6, 2025
311c840
use Class.cast() to remove all the horrible unchecked type casts in t…
gavinking Dec 6, 2025
9ed9aeb
more use of Class.cast() instead of unchecked casts and fallout
gavinking Dec 6, 2025
265a5a1
slight simplification to SessionImpl.setProperty()
gavinking Dec 6, 2025
e4f605d
attempt to make checker happy
gavinking Dec 6, 2025
acfcfcc
hack around an issue with mapping arrays of Date as SQL ARRAYs
gavinking Dec 7, 2025
c2272a7
misc code cleanups
gavinking Dec 7, 2025
78da9ff
fix up a bunch more unchecked casts
gavinking Dec 7, 2025
74d0295
work around a design problem (possibly a bug) affecting hibernate-vector
gavinking Dec 7, 2025
0cdbc4d
deprecate the unsafe methods of JpaMetamodel
gavinking Dec 7, 2025
ccf42f0
actually fix up the unsafe methods of JpaMetamodel
gavinking Dec 7, 2025
e491d33
fix an accidental change that broke Reactive
gavinking Dec 7, 2025
dadc5ed
type inference in the SQM tree
gavinking Dec 7, 2025
6bb96fc
fixed the unsoundness of the coerce() method
gavinking Dec 7, 2025
9e40f1c
clean up obsolete code in EnabledCaching
gavinking Dec 7, 2025
433d83b
try to improve type safety in JavaTypeRegistry and MutableMutabilityP…
gavinking Dec 7, 2025
58c588d
use 'var' in DynamicInstantiation stuff
gavinking Dec 8, 2025
643b02b
clean up warnings in a test
gavinking Dec 8, 2025
bbf0c5f
more work on coercion, casting, and isInstance()
gavinking Dec 8, 2025
9f12e2c
clean up lost of calls to unsafe JavaTypeRegistry.getDescriptor() method
gavinking Dec 8, 2025
8a2f5d4
fix the lack of type safety of getJdbcRecommendedJavaTypeMapping()
gavinking Dec 8, 2025
9ce4619
HHH-19972 Ignore PK violation when inserting just primary key columns
beikov Dec 2, 2025
06bc35a
first phase of strict checking of arguments to query parameters
gavinking Nov 30, 2025
0ee5b79
fix a user-written test that asserted some unreasonable things
gavinking Nov 30, 2025
80acf21
simplify the exception model for query arguments/parameters
gavinking Nov 30, 2025
043ee48
very minor code refactoring
gavinking Nov 30, 2025
1c548c0
introduce QueryArguments
gavinking Dec 1, 2025
51c9d54
more work on type inference/safety
gavinking Dec 8, 2025
fa56009
pull implementations down off SessionFactory
gavinking Dec 8, 2025
47d28d1
get rid of unnecessary EntityNameResolverSessionFactory + extract met…
gavinking Dec 8, 2025
b069483
extract duplicated code in GraphParsing
gavinking Dec 8, 2025
7f34241
factor out GraphParserEntityXXXXXResolver interfaces
gavinking Dec 8, 2025
4c06810
some refactoring and cleanups in the graph package
gavinking Dec 9, 2025
ffb7d28
add an additional override for consistency
gavinking Dec 9, 2025
b1aad76
HHH-19979 handle @NamedEntityGraph with defaulted name
gavinking Dec 9, 2025
186aa16
HHH-19955 Fix for NullpointerException in EntityEntryContext in some …
werner77 Nov 25, 2025
ce1751b
move two @Internal interfaces into org.hibernate.query.internal
gavinking Dec 9, 2025
da91390
rethink of the previous approach to query parameter binding validation
gavinking Dec 9, 2025
0722f2c
rethink of the previous approach to query parameter binding validation
gavinking Dec 9, 2025
8496f3c
HHH-19980 Keep non-BulkOperationCleanupAction in the after completion…
marko-bekhta Dec 9, 2025
8e1bf20
small fix in README
sebersole Dec 10, 2025
cb6d2ce
[Jenkins release job] changelog.txt updated by release build 7.2.0.CR4
Hibernate-CI Dec 10, 2025
1a11d3f
[Jenkins release job] Preparing release 7.2.0.CR4
Hibernate-CI Dec 10, 2025
f144b9f
[Jenkins release job] Preparing next development iteration
Hibernate-CI Dec 10, 2025
cbcdd23
HHH-7287 - Problem in caching proper natural-id-values when obtaining…
sebersole Dec 11, 2025
e2b93cb
HHH-7287 - Problem in caching proper natural-id-values when obtaining…
sebersole Dec 11, 2025
ddb8921
Workaround JDK 17 javac bug for switch expression compilation
beikov Dec 12, 2025
d1401f7
HHH-19976 Don't adopt AdjustableBasicType name to create derived type
beikov Dec 4, 2025
f24de36
HHH-3192 - SchemaValidator column nullability check
sebersole Dec 11, 2025
6cecc13
Create 7.2 branch
sebersole Dec 12, 2025
bce6ff5
HHH-16383 - NaturalIdClass
sebersole Nov 19, 2025
67d35af
HHH-6598 - Immutable entities should not have up-to-date checks perfo…
sebersole Dec 11, 2025
b6748cd
Use DateJavaType instead of JdbcXxxxJavaTypes to represent fields of …
gavinking Dec 10, 2025
8d81010
fix tests after big change to handling of Date
gavinking Dec 10, 2025
e18b585
clean up an antiquated test
gavinking Dec 10, 2025
3c7df01
fix broken test
gavinking Dec 10, 2025
ac1dcfd
unbreak the imm_date type and friends
gavinking Dec 10, 2025
d001986
back out a change that seems to be unnecessary
gavinking Dec 10, 2025
6fe4eac
fix Envers test after change to Dates
gavinking Dec 10, 2025
8f7e04b
adapt Envers to change in Dates
gavinking Dec 10, 2025
1e83a3a
more test fixes for new Date stuff
gavinking Dec 10, 2025
2a5db7a
fix up unchecked casts in resolveTypeForPrecision()
gavinking Dec 10, 2025
a8b9d60
cleanup after the big work on Date
gavinking Dec 10, 2025
b155512
extract some functions in InferredBasicValueResolver
gavinking Dec 10, 2025
c973caa
remove one last dodgy typing workaround after Date stuff
gavinking Dec 10, 2025
603e896
get Session past spotless
gavinking Dec 12, 2025
d7b5bd3
rethink of the previous approach to query parameter binding validation
gavinking Dec 10, 2025
ad525a6
misc things in engine
gavinking Dec 10, 2025
d952505
more work on bindings
gavinking Dec 10, 2025
2a2b995
eliminate more unchecked casts and an obsolete method
gavinking Dec 11, 2025
2c5004d
fix most of the unsoundness
gavinking Dec 11, 2025
c3d33a5
clean up the methods of QueryParameterBindingImpl
gavinking Dec 11, 2025
0a6fd60
minor cleanups to DomainParameterXref
gavinking Dec 11, 2025
83e45dc
refactor away code duplication in AfterTransactionCompletionProcessQueue
gavinking Dec 12, 2025
04c266d
change the assertion in a test
gavinking Dec 12, 2025
734d974
overwrite the previous useless test for @Source
gavinking Dec 12, 2025
de3d142
introduce DetachedObjectException
gavinking Nov 22, 2025
4806217
cleanups after introduction of DetachedObjectException
gavinking Nov 24, 2025
c8868e6
HHH-18998 pass annotation to constructor of UserType
gavinking Jan 22, 2025
47a7f54
add a test for a custom type with constructor on @ElenentCollection
gavinking Dec 13, 2025
70b692c
extremely minor things
gavinking Dec 13, 2025
d4bfb31
fix some ver minor typos
gavinking Dec 13, 2025
2659cfb
HHH-19989 introduce RemovalsMode.EXCLUDE
gavinking Dec 13, 2025
0d53890
HHH-19983: Config for running tests on Spanner emulator
rayudu3745 Dec 10, 2025
c49afad
Bump version to 7.3
dreab8 Dec 15, 2025
e5277e0
HHH-19826 Add array_reverse and array_sort functions
yybmion Dec 5, 2025
ab2c2d3
HHH-19890 Add Jackson 3 FormatMapper support
nrayburn-tech Dec 1, 2025
eb44008
HHH-19991: Provide some fixes for spanner dialect
rayudu3745 Dec 15, 2025
c7b8648
Fix wrong version in What's New title
dreab8 Dec 15, 2025
b64f42f
HHH-19964 - Allow json serialization of Object valued attribute
jrenaat Dec 1, 2025
3a66432
HHH-19964 - Add test for json serialization of Object valued attribut…
jrenaat Dec 3, 2025
1076ffa
HHH-19978 Support type variable members also in abstract entities
beikov Dec 5, 2025
93c4950
Update README.adoc - build now requires JDK 25
mbellade Nov 20, 2025
7dc3e68
HHH-19949 Test to show that the issue has been resolved by HHH-19874
dreab8 Dec 3, 2025
2d35efa
HHH-19991: fixes build failures due to spanner change
rayudu3745 Dec 16, 2025
4c42ff2
HHH-19964 Fixup type check in AbstractJsonFormatMapper#toString
beikov Dec 16, 2025
9639798
a couple of tiny optimizations, and use of 'var'
gavinking Dec 16, 2025
1168b5a
check an unchecked cast
gavinking Dec 16, 2025
3d43c69
Revisit GeneratorBinder's method accessibility
quaff Dec 16, 2025
9424258
HHH-16383 - NaturalIdClass
sebersole Dec 15, 2025
6be7d76
HHH-16383 - NaturalIdClass
sebersole Dec 16, 2025
8ca24d9
HHH-5798 - DiscriminatorValue on abstract entity classes
sebersole Dec 16, 2025
4d780fb
HHH-5798 Fix whitespace in test causing build failures
mbellade Dec 17, 2025
82d913d
HHH-19997 Fix TiDB support in docker_db.sh and local.databases.gradle
alastori Dec 17, 2025
645b494
HHH-19935 Make sure that increment to current sequence can not be zero
cigaly Nov 17, 2025
0ba882b
cleanups in ExecuteWithTemporaryTableHelper
gavinking Dec 17, 2025
921bf53
extract two methods in JTASessionContext
gavinking Dec 17, 2025
189a07d
mention InetAddress in docs
gavinking Dec 17, 2025
52fa8ac
some minor refactorings around Column
gavinking Dec 18, 2025
65ad36a
yet another warning
gavinking Dec 18, 2025
08cef4d
add more code examples to @NaturalId
gavinking Dec 16, 2025
77a53bb
Update the snapshot repository for JPA
marko-bekhta Dec 15, 2025
994a521
minor code improvements
gavinking Dec 18, 2025
8711f52
HHH-14584 Allow PhysicalNamingStrategy implementations to detect when…
peter1123581321 Jun 16, 2025
a10f436
HHH-19962 HHH-19985 Add test for issue
mbellade Dec 11, 2025
6d9e54b
HHH-19962 Use selection expression for anonymous tuple basic values
mbellade Dec 11, 2025
0fef0e4
HHH-19985 Fix sub-selection index in anonymous tuple embeddable values
mbellade Dec 11, 2025
e72143d
fix the unchecked cast when initializing AnnotationBasedGenerator
gavinking Dec 19, 2025
09f4b96
HHH-19919 Re-use existing initialized collection instance when readin…
mbellade Nov 18, 2025
633a9ca
fix CriteriaToBigDecimalTest which used strings in metamodel to do wr…
gavinking Dec 19, 2025
258c733
skip more locking tests on Informix
gavinking Dec 19, 2025
775b3a5
add note about failure on Informix
gavinking Dec 19, 2025
7db15d4
clean up some ugly code formatting in InformixDialect
gavinking Dec 19, 2025
af5e540
HHH-20008 Fix MEMBER OF performance by using EXISTS translation
beikov Dec 19, 2025
f8d7767
fix a typo in jdoc
gavinking Dec 22, 2025
afbad8c
HHH-19993 Introduce UserTypeCreationContext and AnnotationBasedUserType
quaff Dec 16, 2025
82281c5
HHH-20009 Fix docker_db.sh & fix env var typo
namuuCY Dec 20, 2025
6233ac7
minor refactor to new code supporting AnnotationBasedUserType
gavinking Dec 23, 2025
a645529
make JAXB properly optional when hibernate.xml_mapping_enabled=false
gavinking Dec 23, 2025
82d9d81
first pass at ripping out Classmate
gavinking Dec 23, 2025
ec79fe1
second pass at ripping out Classmate
gavinking Dec 23, 2025
8469519
rename/move the new helper classes
gavinking Dec 23, 2025
7357bfd
put the logging back in
gavinking Dec 23, 2025
744e78a
clean up use of raw types
gavinking Dec 23, 2025
e87fa4f
use arrayType() method instead of newInstance().getClass()
gavinking Dec 23, 2025
d976a76
minor cleanups
gavinking Dec 23, 2025
2ea870b
fix a couple of typing problems in ArrayJdbcType
gavinking Dec 23, 2025
36a4666
clean up generics inferencing code
gavinking Dec 23, 2025
6b9ceae
use more efficient (if correct) implementation of type arg inference
gavinking Dec 23, 2025
024fa31
clean up commented code
gavinking Dec 23, 2025
e377310
clean up new Panache2-related code
gavinking Dec 25, 2025
a411a20
use resource accessor method internally in Spring repository
gavinking Dec 25, 2025
7eb91d7
HHH-20017 Refactor AnnotationBasedGenerator to align with AnnotationB…
quaff Dec 26, 2025
1554982
ver minor code cleanups
gavinking Dec 30, 2025
631d9c2
HHH-20017 align constructor-based Generator initialization with new s…
gavinking Dec 30, 2025
77c6481
update Javadoc
gavinking Dec 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ See link:MAINTAINERS.md#ci[MAINTAINERS.md] for information about CI.

== Building from sources

The build requires at least JDK 21, and produces Java 17 bytecode.
The build requires at least JDK 25, and produces Java 17 bytecode.

Hibernate uses https://gradle.org[Gradle] as its build tool. See the _Gradle Primer_ section below if you are new to
Gradle.
Expand Down
22 changes: 22 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
Hibernate 7 Changelog
=======================

Changes in 7.2.0.CR4 (December 10, 2025)
------------------------------------------------------------------------------------------------------------------------

https://hibernate.atlassian.net/projects/HHH/versions/36476


** Bug
* HHH-19980 In JTA after-completion callbacks may get ignored
* HHH-19979 processor should handle @NamedEntityGraph with defaulted name
* HHH-19975 Calling entityManager.find(clazz, id) with null id throws NullPointerException
* HHH-19972 OptionalTableUpdateOperation can fail on PostgreSQL < 15 and CockroachDB
* HHH-19963 Wrong references in entity fields with circular associations
* HHH-19958 `<generated>` tag in orm.xml is not implemented
* HHH-19955 Thread-safety issue in EntityEntryContext resulting in NullPointerException for Session.contains() calls.
* HHH-19843 Bean Validation may fail on operations with stateless session
* HHH-18871 Nested NativeQuery mappings causing 'Could not locate TableGroup' exception after migration
* HHH-18217 StatelessSession.upsert() for entity with all-null non-id fields, or no non-id field

** Improvement
* HHH-19943 Comparison of generic nested EmbeddedId's fails for JPQL and Criteria API
* HHH-19215 Extends Dialect#addQueryHints to support straight_join syntax

Changes in 7.2.0.CR3 (November 25, 2025)
------------------------------------------------------------------------------------------------------------------------

Expand Down
10 changes: 2 additions & 8 deletions ci/release/Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,9 @@ pipeline {
withEnv([
"DISABLE_REMOTE_GRADLE_CACHE=true"
]) {
def notesFiles = findFiles(glob: 'release_notes.md')
if ( notesFiles.length < 1 ) {
throw new IllegalStateException( "Could not locate `release_notes.md`" )
}
if ( notesFiles.length > 1 ) {
throw new IllegalStateException( "Located more than 1 `release_notes.md`" )
}
def ghReleaseNote = sh(script: 'realpath -e release_notes.md 2>/dev/null', returnStdout: true).trim()

sh ".release/scripts/publish.sh -j --notes=${notesFiles[0].path} ${env.SCRIPT_OPTIONS} ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION} ${env.GIT_BRANCH} "
sh ".release/scripts/publish.sh -j ${ghReleaseNote != '' ? '--notes=' + ghReleaseNote : ''} ${env.SCRIPT_OPTIONS} ${env.PROJECT} ${env.RELEASE_VERSION} ${env.DEVELOPMENT_VERSION} ${env.GIT_BRANCH} "
}
}
}
Expand Down
116 changes: 109 additions & 7 deletions docker_db.sh
Original file line number Diff line number Diff line change
Expand Up @@ -218,53 +218,59 @@ mariadb_setup() {
echo "MySQL databases were successfully setup"
}

POSTGRESQL_PLATFORM_OPTION=""
if [[ "$IS_OSX" == "true" ]]; then
# PostGIS images only support amd64, so we force emulation on macOS
POSTGRESQL_PLATFORM_OPTION="--platform linux/amd64"
fi

postgresql() {
postgresql_18
}

postgresql_13() {
$CONTAINER_CLI rm -f postgres || true
$CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql/data -d ${DB_IMAGE_POSTGRESQL_13:-docker.io/postgis/postgis:13-3.1} \
$CONTAINER_CLI run --name postgres ${POSTGRESQL_PLATFORM_OPTION} -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql/data -d ${DB_IMAGE_POSTGRESQL_13:-docker.io/postgis/postgis:13-3.1} \
-c fsync=off -c synchronous_commit=off -c full_page_writes=off -c shared_buffers=256MB -c maintenance_work_mem=256MB -c max_wal_size=1GB -c checkpoint_timeout=1d
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-13-pgvector'
postgresql_setup
}

postgresql_14() {
$CONTAINER_CLI rm -f postgres || true
$CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql/data -d ${DB_IMAGE_POSTGRESQL_14:-docker.io/postgis/postgis:14-3.3} \
$CONTAINER_CLI run --name postgres ${POSTGRESQL_PLATFORM_OPTION} -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql/data -d ${DB_IMAGE_POSTGRESQL_14:-docker.io/postgis/postgis:14-3.3} \
-c fsync=off -c synchronous_commit=off -c full_page_writes=off -c shared_buffers=256MB -c maintenance_work_mem=256MB -c max_wal_size=1GB -c checkpoint_timeout=1d
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-14-pgvector'
postgresql_setup
}

postgresql_15() {
$CONTAINER_CLI rm -f postgres || true
$CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql/data -d ${DB_IMAGE_POSTGRESQL_15:-docker.io/postgis/postgis:15-3.3} \
$CONTAINER_CLI run --name postgres ${POSTGRESQL_PLATFORM_OPTION} -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql/data -d ${DB_IMAGE_POSTGRESQL_15:-docker.io/postgis/postgis:15-3.3} \
-c fsync=off -c synchronous_commit=off -c full_page_writes=off -c shared_buffers=256MB -c maintenance_work_mem=256MB -c max_wal_size=1GB -c checkpoint_timeout=1d
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-15-pgvector'
postgresql_setup
}

postgresql_16() {
$CONTAINER_CLI rm -f postgres || true
$CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql/data -d ${DB_IMAGE_POSTGRESQL_16:-docker.io/postgis/postgis:16-3.4} \
$CONTAINER_CLI run --name postgres ${POSTGRESQL_PLATFORM_OPTION} -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql/data -d ${DB_IMAGE_POSTGRESQL_16:-docker.io/postgis/postgis:16-3.4} \
-c fsync=off -c synchronous_commit=off -c full_page_writes=off -c shared_buffers=256MB -c maintenance_work_mem=256MB -c max_wal_size=1GB -c checkpoint_timeout=1d
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-16-pgvector'
postgresql_setup
}

postgresql_17() {
$CONTAINER_CLI rm -f postgres || true
$CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql/data -d ${DB_IMAGE_POSTGRESQL_17:-docker.io/postgis/postgis:17-3.5} \
$CONTAINER_CLI run --name postgres ${POSTGRESQL_PLATFORM_OPTION} -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql/data -d ${DB_IMAGE_POSTGRESQL_17:-docker.io/postgis/postgis:17-3.5} \
-c fsync=off -c synchronous_commit=off -c full_page_writes=off -c shared_buffers=256MB -c maintenance_work_mem=256MB -c max_wal_size=1GB -c checkpoint_timeout=1d
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-17-pgvector'
postgresql_setup
}

postgresql_18() {
$CONTAINER_CLI rm -f postgres || true
$CONTAINER_CLI run --name postgres -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql -d ${DB_IMAGE_POSTGRESQL_17:-docker.io/postgis/postgis:18-3.6} \
$CONTAINER_CLI run --name postgres ${POSTGRESQL_PLATFORM_OPTION} -e POSTGRES_USER=hibernate_orm_test -e POSTGRES_PASSWORD=hibernate_orm_test -e POSTGRES_DB=hibernate_orm_test -p5432:5432 --tmpfs /var/lib/postgresql -d ${DB_IMAGE_POSTGRESQL_18:-docker.io/postgis/postgis:18-3.6} \
-c fsync=off -c synchronous_commit=off -c full_page_writes=off -c shared_buffers=256MB -c maintenance_work_mem=256MB -c max_wal_size=1GB -c checkpoint_timeout=1d
$CONTAINER_CLI exec postgres bash -c '/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y && apt install -y postgresql-18-pgvector'
postgresql_setup
Expand Down Expand Up @@ -1282,7 +1288,68 @@ EOF
}

tidb() {
tidb_5_4
tidb_8_5
}

tidb_8_5() {
$CONTAINER_CLI rm -f tidb || true
$CONTAINER_CLI run --name tidb -p4000:4000 -d ${DB_IMAGE_TIDB_8_5:-docker.io/pingcap/tidb:v8.5.4}

# Wait for TiDB to start
OUTPUT=
n=0
until [ "$n" -gt 15 ]; do
OUTPUT=$($CONTAINER_CLI logs tidb 2>&1)
if [[ $OUTPUT == *"server is running"* ]]; then
break;
fi
n=$((n+1))
echo "Waiting for TiDB to start..."
sleep 5
done

if [ "$n" -gt 15 ]; then
echo "TiDB failed to start after 75 seconds"
exit 1
else
echo "TiDB successfully started"
fi

# Wait for TiDB to accept connections
n=0
until [ "$n" -gt 10 ]; do
if $CONTAINER_CLI run --rm --network container:tidb docker.io/mysql:8.0 \
mysqladmin -h 127.0.0.1 -P 4000 -uroot ping >/dev/null 2>&1; then
break;
fi
n=$((n+1))
echo "Waiting for TiDB to be ready..."
sleep 3
done

if [ "$n" -gt 10 ]; then
echo "TiDB failed to become ready after 30 seconds"
exit 1
else
echo "TiDB is ready"
fi

# Create databases
databases=()
for n in $(seq 1 $DB_COUNT)
do
databases+=("hibernate_orm_test_${n}")
done
create_cmd=
create_cmd+="CREATE DATABASE IF NOT EXISTS hibernate_orm_test;"
create_cmd+="CREATE USER IF NOT EXISTS 'hibernate_orm_test'@'%' IDENTIFIED BY 'hibernate_orm_test';"
create_cmd+="GRANT ALL ON hibernate_orm_test.* TO 'hibernate_orm_test'@'%';"
for i in "${!databases[@]}";do
create_cmd+="CREATE DATABASE IF NOT EXISTS ${databases[i]}; GRANT ALL ON ${databases[i]}.* TO 'hibernate_orm_test'@'%';"
done
$CONTAINER_CLI run --rm --network container:tidb docker.io/mysql:8.0 \
mysql -h 127.0.0.1 -P 4000 -uroot -e "${create_cmd}" 2>/dev/null
echo "TiDB databases were successfully setup"
}

tidb_5_4() {
Expand Down Expand Up @@ -1370,6 +1437,38 @@ informix_12_10() {
fi
}

spanner() {
spanner_emulator
}

spanner_emulator() {

$CONTAINER_CLI rm -f spanner || true
# Run emulator (gRPC on 9010, REST on 9020)
$CONTAINER_CLI run --name spanner -d \
-p 9010:9010 \
-p 9020:9020 \
${SPANNER_EMULATOR:-gcr.io/cloud-spanner-emulator/emulator:1.5.45}

# Wait for emulator to be ready (check logs for known messages)
n=0
until [ "$n" -ge 20 ]; do
OUTPUT="$($CONTAINER_CLI logs spanner 2>&1 || true)"
if [[ "$OUTPUT" == *"gRPC server listening"* ]] || [[ "$OUTPUT" == *"Cloud Spanner emulator running"* ]]; then
echo "Cloud Spanner emulator started."
break
fi
echo "Waiting for Cloud Spanner emulator to start..."
n=$((n+1))
sleep 3
done

if [ "$n" -ge 20 ]; then
echo "Cloud Spanner emulator failed to start after 1 minute"
exit 1
fi
}

if [ -z ${1} ]; then
echo "No db name provided"
echo "Provide one of:"
Expand Down Expand Up @@ -1413,10 +1512,13 @@ if [ -z ${1} ]; then
echo -e "\tpostgresql_13"
echo -e "\tsybase"
echo -e "\ttidb"
echo -e "\ttidb_8_5"
echo -e "\ttidb_5_4"
echo -e "\informix"
echo -e "\informix_14_10"
echo -e "\informix_12_10"
echo -e "\tspanner"
echo -e "\tspanner_emulator"
else
${1}
fi
11 changes: 11 additions & 0 deletions documentation/src/main/asciidoc/introduction/Advanced.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,17 @@ On the other hand, the following annotations specify how a collection should be

Under the covers, Hibernate uses a `TreeSet` or `TreeMap` to maintain the collection in sorted order.

[CAUTION]
====
The unowned (`mappedBy`) side of a bidirectional association is not responsible for specifying column mappings.
So it's wrong in principle to use `@OrderColumn` or `@MapKeyColumn` on the unowned side of an association mapping.
But for unowned collections, we may use `@OrderBy` or `@MapKey` instead.
That is:

- You can use `@OrderColumn` or `@MapKeyColumn` with an `@ElementCollection`, owned `@ManyToMany`, or owned `@OneToMany`.
- But use `@OrderBy` or `@MapKey` when it's an _unowned_ `@ManyToMany` or `@OneToMany`.
====

[[any]]
=== Any mappings

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ and `org.ehcache:ehcache`
and `com.github.ben-manes.caffeine:jcache`
| Distributed second-level cache support via {infinispan}[Infinispan] | `org.infinispan:infinispan-hibernate-cache-v60`
// | SCRAM authentication support for PostgreSQL | `com.ongres.scram:client:2.1`
| A JSON serialization library for working with JSON datatypes, for example, {jackson}[Jackson] or {yasson}[Yasson] |
`com.fasterxml.jackson.core:jackson-databind` +
| A JSON serialization library for working with JSON datatypes, for example, {jackson}[Jackson 2], {jackson3}[Jackson 3] or {yasson}[Yasson] |
`com.fasterxml.jackson.core:jackson-databind`, `tools.jackson.core:jackson-databind` +
or `org.eclipse:yasson`
| <<spatial,Hibernate Spatial>> | `org.hibernate.orm:hibernate-spatial`
| <<envers,Envers>>, for auditing historical data | `org.hibernate.orm:hibernate-envers`
Expand Down
16 changes: 16 additions & 0 deletions documentation/src/main/asciidoc/introduction/Entities.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,21 @@ Hibernate automatically generates a `UNIQUE` constraint on the columns mapped by
Consider using the natural id attributes to implement <<equals-and-hash>>.
====

In cases where the natural id is defined by multiple attributes, Hibernate also offers the link:{doc-javadoc-url}org/hibernate/annotations/NaturalIdClass.html[`@NaturalIdClass`] annotation which acts similarly to the Jakarta Persistence `@IdClass` annotation for <<load-by-natural-id,find operations>> -

[source,java]
----
record BookKey(String isbn, int printing) {}

@Entity
@NaturalIdClass(BookKey.class)
class Book {
...
}
----

See the link:{doc-user-guide-url}#naturalid[User Guide] for more details about natural ids.

The payoff for doing this extra work, as we will see <<natural-id-cache,much later>>, is that we can take advantage of optimized natural id lookups that make use of the second-level cache.

Note that even when you've identified a natural key, we still recommend the use of a generated surrogate key in foreign keys, since this makes your data model _much_ easier to change.
Expand Down Expand Up @@ -586,6 +601,7 @@ Hibernate slightly extends this list with the following types:
| Additional date/time types | `java.time` | `Duration`, `ZoneId`, `ZoneOffset`, and even `ZonedDateTime`
| JDBC LOB types | `java.sql` | `Blob`, `Clob`, `NClob`
| Java class object | `java.lang` | `Class`
| Internet addresses | `java.net` | `InetAddress`
| Miscellaneous types | `java.util` | `Currency`, `Locale`, `URL`, `TimeZone`
|====

Expand Down
27 changes: 26 additions & 1 deletion documentation/src/main/asciidoc/introduction/Interacting.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ Modifications are automatically detected when the session is <<flush,flushed>>.

On the other hand, except for `getReference()`, the following operations all result in immediate access to the database:

[[methods-for-reading]]
.Methods for reading and locking data
[%breakable,cols="30,~"]
|===
Expand Down Expand Up @@ -368,9 +369,30 @@ The following code results in a single SQL `select` statement:
List<Book> books = session.findMultiple(Book.class, bookIds);
----

[[load-by-natural-id]]
As discussed <<natural-id-attributes,earlier>>, Hibernate offers the ability to map a natural id and perform load operations using that natural id.
This is accomplished using the `KeyType#NATURAL` `FindOption` -

[source,java]
----
var bookKey = new BookKey(...);
var book = session.find(Book.class, bookKey, NATURAL);
var books = session.findMultiple(Book.class, List.of(bookKey), NATURAL);
----

When loading by natural id, the type of value accepted depends on the type of natural id.
For single-attribute natural ids, whether defined by a basic or embedded type, the attribute type should be used.
For multi-attribute natural ids, Hibernate will accept a number of forms:

* If a link:{doc-javadoc-url}org/hibernate/annotations/NaturalIdClass.html[`@NaturalIdClass`] is defined, an instance of the natural id class may be used.
* An array of the individual attribute values, ordered alphabetically by name, may be used.
* A `Map` of the individual attribute values, keyed by the attribute name, may be used.

Each of the operations we've seen so far affects a single entity instance passed as an argument.
But there's a way to set things up so that an operation will propagate to associated entities.

See the link:{doc-user-guide-url}#find-by-natural-id[User Guide] for more details about loading by natural ids.

[[cascade]]
=== Cascading persistence operations

Expand Down Expand Up @@ -595,7 +617,8 @@ Therefore, Hibernate has some APIs that streamline certain more complicated look

[NOTE]
====
Since the introduction of `FindOption` in JPA 3.2, `byId()` is now much less useful.
Since the introduction of `FindOption` in JPA 3.2, `byId()` is now much less useful and deprecated.
Instead, use `find()` and `findMultiple()` as discussed <<methods-for-reading,earlier>>.
====

Batch loading is very useful when we need to retrieve multiple instances of the same entity class by id:
Expand Down Expand Up @@ -627,6 +650,8 @@ We also have some operations for working with lookups by <<natural-identifiers,
| `byMultipleNaturalId()` | Lets us load a _batch_ of natural ids at the same time
|===

Again, see the link:{doc-user-guide-url}#find-by-natural-id[User Guide] for more details about loading by natural ids.

Here's how we can retrieve an entity by its composite natural id:

[source,java]
Expand Down
9 changes: 8 additions & 1 deletion documentation/src/main/asciidoc/introduction/Mapping.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -809,13 +809,20 @@ class Person {
----

We also need to add Jackson or an implementation of JSONB—for example, Yasson—to our runtime classpath.
To use Jackson we could add this line to our Gradle build:
To use Jackson 2 we could add this line to our Gradle build:

[source,groovy]
----
runtimeOnly 'com.fasterxml.jackson.core:jackson-databind:{jacksonVersion}'
----

To use Jackson 3 we could add this line to our Gradle build:

[source,groovy]
----
runtimeOnly 'tools.jackson.core:jackson-databind:{jackson3Version}'
----

Now the `name` column of the `Author` table will have the type `jsonb`, and Hibernate will automatically use Jackson to serialize a `Name` to and from JSON format.

[[miscellaneous-mappings]]
Expand Down
Loading
Loading