Skip to content

Commit 76d0809

Browse files
committed
Merge branch 'main' into dialect_case_insensitive_query_pattern
2 parents dbbe1db + cda55ae commit 76d0809

File tree

224 files changed

+5564
-4180
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

224 files changed

+5564
-4180
lines changed

documentation/src/main/asciidoc/introduction/Interacting.adoc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,8 @@ When a transaction rolls back, Hibernate makes no attempt to roll back the state
241241
After a transaction rollback, the persistence context must be discarded, and the state of its entities must be assumed inconsistent with the state held by the database.
242242
====
243243

244+
The interface link:{doc-javadoc-url}org/hibernate/Transaction.html[`Transaction`] extends `EntityTransaction` with some additional operations, including the ability to register transaction completion callbacks.
245+
244246
[[persistence-operations]]
245247
=== Operations on the persistence context
246248

@@ -743,13 +745,13 @@ session.getTransaction().commit();
743745
| `ALWAYS` | | Flush before transaction commit, and before execution of every query
744746
|===
745747

746-
A second way to reduce the cost of flushing is to load entities in _read-only_ mode:
748+
A second way to reduce the cost of flushing is to load entities in link:{doc-javadoc-url}org/hibernate/Session.html#setDefaultReadOnly(boolean)[_read-only_ mode]:
747749

748750
- `Session.setDefaultReadOnly(true)` specifies that all entities loaded by a given session should be loaded in read-only mode by default,
749751
- `SelectionQuery.setReadOnly(true)` specifies that every entity returned by a given query should be loaded in read-only mode, and
750752
- `Session.setReadOnly(Object, true)` specifies that a given entity already loaded by the session should be switched to read-only mode.
751753

752-
Hibernate's `ReadOnlyMode` is a custom `FindOption`:
754+
Hibernate's link:{doc-javadoc-url}org/hibernate/ReadOnlyMode.html[`ReadOnlyMode`] is a custom `FindOption`:
753755

754756
[source,java]
755757
----

documentation/src/main/asciidoc/introduction/Mapping.adoc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,15 @@ is a bad idea, since it's impossible to create a foreign key constraint that tar
168168
// Hibernate doesn't support mixing ``InheritanceType``s within a single entity hierarchy.
169169
// However, it's possible to emulate a mix of `SINGLE_TABLE` and `JOINED` inheritance using the `@SecondaryTable` annotation.
170170

171+
[CAUTION]
172+
====
173+
It's quite easy to overuse inheritance.
174+
We've occasionally seen extreme cases where a `JOINED` inheritance hierarchy includes _hundreds_ of entities, spanning hundreds of tables.
175+
Efficiently querying such a hierarchy is an almost impossible task for Hibernate.
176+
Fortunately, a `JOINED` inheritance relationship can always be remodeled as a <<one-to-one-pk,one-to-one association>>, allowing much more efficient queries.
177+
In general, a single entity inheritance hierarchy should never span more than a few tables, including secondary tables.
178+
====
179+
171180
[[table-mappings]]
172181
=== Mapping to tables
173182

documentation/src/main/asciidoc/querylanguage/Expressions.adoc

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,7 @@ Their syntax is defined by:
14951495
include::{extrasdir}/predicate_like_bnf.txt[]
14961496
----
14971497

1498-
The expression on the right is a pattern, where:
1498+
The expression on the right is usually a SQL-style pattern, where:
14991499

15001500
* `_` matches any single character,
15011501
* `%` matches any number of characters, and
@@ -1509,6 +1509,14 @@ from Book where title not like '% for Dummies'
15091509

15101510
The optional `escape` character allows a pattern to include a literal `_` or `%` character.
15111511

1512+
Alternatively, the `regexp` keyword specifies that the pattern should be interpreted as a regular expression:
1513+
1514+
[[like-regexp-predicate-example]]
1515+
[source, hql]
1516+
----
1517+
from Book where title not like regexp '.+ for Dummies'
1518+
----
1519+
15121520
As you can guess, `not like` and `not ilike` are the enemies of `like` and `ilike`, and evaluate to the exact opposite boolean values.
15131521

15141522
[[in-predicate]]
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
expression "NOT"? ("LIKE" | "ILIKE") expression ("ESCAPE" character)?
1+
expression "NOT"? ("LIKE" | "ILIKE") REGEXP? expression ("ESCAPE" character)?

documentation/src/main/asciidoc/topical/registries/ServiceRegistries.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ service is defined by the interface (service role) +org.hibernate.engine.jdbc.co
2828
which declares methods for obtaining and releasing the Connections. There are then multiple implementations of that
2929
service contract, varying in how they actually manage the Connections:
3030

31-
* +org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl+ for using a +javax.sql.DataSource+
31+
* +org.hibernate.engine.jdbc.connections.internal.DataSourceConnectionProvider+ for using a +javax.sql.DataSource+
3232
* +org.hibernate.c3p0.internal.C3P0ConnectionProvider+ for using a C3P0 Connection pool
3333
* etc.
3434

hibernate-agroal/src/main/java/org/hibernate/agroal/internal/AgroalConnectionProvider.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import java.io.Serial;
88
import java.sql.Connection;
99
import java.sql.SQLException;
10-
import javax.sql.DataSource;
1110
import java.util.Map;
1211
import java.util.function.Consumer;
1312
import java.util.function.Function;
@@ -84,9 +83,9 @@ public class AgroalConnectionProvider implements ConnectionProvider, Configurabl
8483

8584
private static String extractIsolationAsString(Map<String, Object> properties) {
8685
final Integer isolation = ConnectionProviderInitiator.extractIsolation( properties );
87-
return isolation != null ?
86+
return isolation != null
8887
// Agroal resolves transaction isolation from the 'nice' name
89-
toIsolationNiceName( isolation )
88+
? toIsolationNiceName( isolation )
9089
: null;
9190
}
9291

@@ -116,9 +115,7 @@ public void configure(Map<String, Object> properties) throws HibernateException
116115
: String.valueOf( 10 );
117116
config.put( AgroalSettings.AGROAL_MAX_SIZE, maxSize );
118117
}
119-
final AgroalPropertiesReader agroalProperties =
120-
new AgroalPropertiesReader( CONFIG_PREFIX )
121-
.readProperties( config );
118+
final var agroalProperties = new AgroalPropertiesReader( CONFIG_PREFIX ).readProperties( config );
122119
agroalProperties.modify()
123120
.connectionPoolConfiguration( cp -> cp.connectionFactoryConfiguration( cf -> {
124121
copyProperty( properties, JdbcSettings.DRIVER, cf::connectionProviderClassName, identity() );
@@ -205,22 +202,22 @@ public DatabaseConnectionInfo getDatabaseConnectionInfo(Dialect dialect) {
205202

206203
@Override
207204
public boolean isUnwrappableAs(Class<?> unwrapType) {
208-
return ConnectionProvider.class.equals( unwrapType )
209-
|| AgroalConnectionProvider.class.isAssignableFrom( unwrapType )
210-
|| DataSource.class.isAssignableFrom( unwrapType );
205+
return unwrapType.isAssignableFrom( AgroalConnectionProvider.class )
206+
|| unwrapType.isAssignableFrom( AgroalDataSource.class );
211207
}
212208

213209
@Override
214210
@SuppressWarnings( "unchecked" )
215211
public <T> T unwrap(Class<T> unwrapType) {
216-
if ( ConnectionProvider.class.equals( unwrapType )
217-
|| AgroalConnectionProvider.class.isAssignableFrom( unwrapType ) ) {
212+
if ( unwrapType.isAssignableFrom( AgroalConnectionProvider.class ) ) {
218213
return (T) this;
219214
}
220-
if ( DataSource.class.isAssignableFrom( unwrapType ) ) {
215+
else if ( unwrapType.isAssignableFrom( AgroalDataSource.class ) ) {
221216
return (T) agroalDataSource;
222217
}
223-
throw new UnknownUnwrapTypeException( unwrapType );
218+
else {
219+
throw new UnknownUnwrapTypeException( unwrapType );
220+
}
224221
}
225222

226223
// --- Stoppable

hibernate-c3p0/src/main/java/org/hibernate/c3p0/internal/C3P0ConnectionProvider.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,17 @@ public void closeConnection(Connection connection) throws SQLException {
115115

116116
@Override
117117
public boolean isUnwrappableAs(Class<?> unwrapType) {
118-
return ConnectionProvider.class.equals( unwrapType )
119-
|| C3P0ConnectionProvider.class.isAssignableFrom( unwrapType )
120-
|| DataSource.class.isAssignableFrom( unwrapType );
118+
return unwrapType.isAssignableFrom( C3P0ConnectionProvider.class )
119+
|| unwrapType.isAssignableFrom( DataSource.class );
121120
}
122121

123122
@Override
124123
@SuppressWarnings("unchecked")
125124
public <T> T unwrap(Class<T> unwrapType) {
126-
if ( ConnectionProvider.class.equals( unwrapType )
127-
|| C3P0ConnectionProvider.class.isAssignableFrom( unwrapType ) ) {
125+
if ( unwrapType.isAssignableFrom( C3P0ConnectionProvider.class ) ) {
128126
return (T) this;
129127
}
130-
else if ( DataSource.class.isAssignableFrom( unwrapType ) ) {
128+
else if ( unwrapType.isAssignableFrom( DataSource.class ) ) {
131129
return (T) dataSource;
132130
}
133131
else {

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/CockroachLegacyDialect.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
import org.hibernate.type.descriptor.jdbc.BlobJdbcType;
7676
import org.hibernate.type.descriptor.jdbc.ClobJdbcType;
7777
import org.hibernate.type.descriptor.jdbc.JdbcType;
78-
import org.hibernate.type.descriptor.jdbc.NClobJdbcType;
7978
import org.hibernate.type.descriptor.jdbc.ObjectNullAsBinaryTypeJdbcType;
8079
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
8180
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
@@ -421,7 +420,7 @@ protected void contributeCockroachTypes(TypeContributions typeContributions, Ser
421420
// Force Blob binding to byte[] for CockroachDB
422421
jdbcTypeRegistry.addDescriptor( Types.BLOB, BlobJdbcType.MATERIALIZED );
423422
jdbcTypeRegistry.addDescriptor( Types.CLOB, ClobJdbcType.MATERIALIZED );
424-
jdbcTypeRegistry.addDescriptor( Types.NCLOB, NClobJdbcType.MATERIALIZED );
423+
jdbcTypeRegistry.addDescriptor( Types.NCLOB, ClobJdbcType.MATERIALIZED );
425424

426425
// The next two contributions are the same as for Postgresql
427426
typeContributions.contributeJdbcType( ObjectNullAsBinaryTypeJdbcType.INSTANCE );

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HANALegacyDialect.java

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,6 @@ private LockingSupport buildLockingSupport() {
214214
return new HANALockingSupport( supportsSkipLocked );
215215
}
216216

217-
218217
@Override
219218
public DatabaseVersion determineDatabaseVersion(DialectResolutionInfo info) {
220219
return HANALegacyServerConfiguration.staticDetermineDatabaseVersion( info );
@@ -652,7 +651,7 @@ public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
652651

653652
@Override
654653
public LockingSupport getLockingSupport() {
655-
return HANALockingSupport.HANA_LOCKING_SUPPORT;
654+
return lockingSupport;
656655
}
657656

658657
@Override
@@ -885,16 +884,6 @@ public SequenceSupport getSequenceSupport() {
885884
return HANASequenceSupport.INSTANCE;
886885
}
887886

888-
@Override
889-
public boolean supportsTableCheck() {
890-
return true;
891-
}
892-
893-
@Override
894-
public boolean supportsTupleDistinctCounts() {
895-
return true;
896-
}
897-
898887
@Override
899888
public boolean dropConstraints() {
900889
return false;

hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/InformixDialect.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,8 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
367367
final TypeConfiguration typeConfiguration = functionContributions.getTypeConfiguration();
368368
final BasicType<String> stringBasicType =
369369
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.STRING );
370+
final BasicType<Boolean> booleanBasicType =
371+
typeConfiguration.getBasicTypeRegistry().resolve( StandardBasicTypes.BOOLEAN );
370372

371373
functionRegistry.registerAlternateKey( "var_samp", "variance" );
372374

@@ -408,6 +410,12 @@ public void initializeFunctionRegistry(FunctionContributions functionContributio
408410
// parameter arguments to trim() require a cast
409411
functionContributions.getFunctionRegistry().register( "trim",
410412
new TrimFunction( this, typeConfiguration, SqlAstNodeRenderingMode.NO_UNTYPED ) );
413+
414+
//TODO: emulate support for the 'i' flag argument
415+
functionRegistry.namedDescriptorBuilder( "regexp_like", "regex_match" )
416+
.setParameterTypes( STRING, STRING )
417+
.setInvariantType( booleanBasicType )
418+
.register();
411419
}
412420

413421
@Override
@@ -572,9 +580,18 @@ public LimitHandler getLimitHandler() {
572580

573581
@Override
574582
public LockingSupport getLockingSupport() {
583+
// TODO: need a custom impl, because:
584+
// 1. Informix does not support 'skip locked'
585+
// 2. Informix does not allow 'for update' with joins
575586
return LockingSupportSimple.STANDARD_SUPPORT;
576587
}
577588

589+
// TODO: remove once we have a custom LockingSupport impl
590+
@Override @Deprecated(forRemoval = true)
591+
public boolean supportsSkipLocked() {
592+
return false;
593+
}
594+
578595
@Override
579596
public boolean supportsIfExistsBeforeTableName() {
580597
return getVersion().isSameOrAfter( 11, 70 );

0 commit comments

Comments
 (0)