Skip to content

Commit 7d28099

Browse files
authored
Merge branch '6.6' into timesten_dialect_updates
2 parents 0b4bc8e + 14b8e31 commit 7d28099

File tree

50 files changed

+1831
-215
lines changed

Some content is hidden

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

50 files changed

+1831
-215
lines changed

changelog.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,33 @@ Hibernate 6 Changelog
33

44
Note: Please refer to JIRA to learn more about each issue.
55

6+
Changes in 6.6.19.Final (June 29, 2025)
7+
------------------------------------------------------------------------------------------------------------------------
8+
9+
https://hibernate.atlassian.net/projects/HHH/versions/33968
10+
11+
** Bug
12+
* [HHH-18837] - Oracle epoch extraction doesn't work with dates
13+
* [HHH-19547] - Misleading exception message at DefaultFlushEntityEventListener - mangled ID - misplaced Entity and EntityEntry ID
14+
* [HHH-19560] - TupleTransformer and ResultListTransformer trash the query interpretation cache
15+
* [HHH-19571] - CloningPropertyCall causes non-deterministic bytecode for AccessOptimizer
16+
* [HHH-19573] - Presence of wrapper byte array pollutes BasicTypeRegistry
17+
* [HHH-19577] - BytecodeProviderImpl.SetPropertyValues wrongly emits duplicate stack map frames
18+
19+
20+
Changes in 6.6.18.Final (June 13, 2025)
21+
------------------------------------------------------------------------------------------------------------------------
22+
23+
https://hibernate.atlassian.net/projects/HHH/versions/33703
24+
25+
** Bug
26+
* [HHH-19533] - Implement equals() and hashCode() for NativeQueryConstructorTransformer
27+
* [HHH-19529] - Check bytecode generated classes with stable names class loaders
28+
* [HHH-18891] - java.lang.AssertionError generated in getResolvedInstance even though NotFound IGNORE set
29+
* [HHH-18876] - ArrayInitializer#resolveInstanceSubInitializers should consider @ListIndexBase
30+
* [HHH-18771] - ListInitializer should consistently consider @ListIndexBase
31+
32+
633
Changes in 6.6.17.Final (May 28, 2025)
734
------------------------------------------------------------------------------------------------------------------------
835

ci/jpa-3.1-tck.Jenkinsfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@Library('hibernate-jenkins-pipeline-helpers@1.13') _
1+
@Library('hibernate-jenkins-pipeline-helpers') _
22

33
// Avoid running the pipeline on branch indexing
44
if (currentBuild.getBuildCauses().toString().contains('BranchIndexingCause')) {
@@ -80,6 +80,7 @@ pipeline {
8080
docker volume create tck-vol
8181
docker run -v ~/.m2/repository/org/hibernate:/root/.m2/repository/org/hibernate:z -v tck-vol:/tck/persistence-tck/tmp/:z -e NO_SLEEP=${params.NO_SLEEP} -e HIBERNATE_VERSION=$HIBERNATE_VERSION --name tck jakarta-tck-runner
8282
docker cp tck:/tck/persistence-tck/tmp/ ./results
83+
rm -Rf ./results/jdk-bundles
8384
"""
8485
archiveArtifacts artifacts: 'results/**'
8586
script {

ci/release/Jenkinsfile

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -209,15 +209,7 @@ pipeline {
209209
configFile(fileId: 'release.config.ssh.knownhosts', targetLocation: "${env.HOME}/.ssh/known_hosts")
210210
]) {
211211
withCredentials([
212-
// https://github.com/gradle-nexus/publish-plugin#publishing-to-maven-central-via-sonatype-ossrh
213-
// TODO: HHH-19309:
214-
// Once we switch to maven-central publishing (from nexus2) we need to add a new credentials
215-
// to use the following env variable names to set the user/password:
216-
// - JRELEASER_MAVENCENTRAL_USERNAME
217-
// - JRELEASER_MAVENCENTRAL_TOKEN
218-
// Also use the new `credentialsId` for Maven Central, e.g.:
219-
// usernamePassword(credentialsId: '???????', passwordVariable: 'JRELEASER_MAVENCENTRAL_TOKEN', usernameVariable: 'JRELEASER_MAVENCENTRAL_USERNAME'),
220-
usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'JRELEASER_NEXUS2_PASSWORD', usernameVariable: 'JRELEASER_NEXUS2_USERNAME'),
212+
usernamePassword(credentialsId: 'central.sonatype.com', passwordVariable: 'JRELEASER_MAVENCENTRAL_TOKEN', usernameVariable: 'JRELEASER_MAVENCENTRAL_USERNAME'),
221213
// https://docs.gradle.org/current/userguide/publishing_gradle_plugins.html#account_setup
222214
usernamePassword(credentialsId: 'gradle-plugin-portal-api-key', passwordVariable: 'GRADLE_PUBLISH_SECRET', usernameVariable: 'GRADLE_PUBLISH_KEY'),
223215
gitUsernamePassword(credentialsId: 'username-and-token.Hibernate-CI.github.com', gitToolName: 'Default'),

ci/snapshot-publish.Jenkinsfile

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,8 @@ pipeline {
4141
script {
4242
withCredentials([
4343
// https://github.com/gradle-nexus/publish-plugin#publishing-to-maven-central-via-sonatype-ossrh
44-
// TODO: HHH-19309:
45-
// Once we switch to maven-central publishing (from nexus2) we need to update credentialsId:
4644
// https://docs.gradle.org/current/samples/sample_publishing_credentials.html#:~:text=via%20environment%20variables
47-
usernamePassword(credentialsId: 'ossrh.sonatype.org', passwordVariable: 'ORG_GRADLE_PROJECT_snapshotsPassword', usernameVariable: 'ORG_GRADLE_PROJECT_snapshotsUsername'),
45+
usernamePassword(credentialsId: 'central.sonatype.com', passwordVariable: 'ORG_GRADLE_PROJECT_snapshotsPassword', usernameVariable: 'ORG_GRADLE_PROJECT_snapshotsUsername'),
4846
string(credentialsId: 'Hibernate-CI.github.com', variable: 'JRELEASER_GITHUB_TOKEN'),
4947
// https://docs.gradle.org/current/userguide/publishing_gradle_plugins.html#account_setup
5048
usernamePassword(credentialsId: 'gradle-plugin-portal-api-key', passwordVariable: 'GRADLE_PUBLISH_SECRET', usernameVariable: 'GRADLE_PUBLISH_KEY'),

gradle/publishing-pom.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ publishing {
6666
}
6767
maven {
6868
name = 'snapshots'
69-
url = "https://oss.sonatype.org/content/repositories/snapshots/"
69+
url = "https://central.sonatype.com/repository/maven-snapshots/"
7070
// So that Gradle uses the `ORG_GRADLE_PROJECT_snapshotsPassword` / `ORG_GRADLE_PROJECT_snapshotsUsername`
7171
// env variables to read the username/password for the `snapshots` repository publishing:
7272
credentials(PasswordCredentials)

gradle/version.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
hibernateVersion=6.6.18-SNAPSHOT
1+
hibernateVersion=6.6.20-SNAPSHOT

hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/ByteBuddyState.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,10 @@ void clearState() {
229229
*/
230230
public Class<?> load(Class<?> referenceClass, String className, BiFunction<ByteBuddy, NamingStrategy, DynamicType.Builder<?>> makeClassFunction) {
231231
try {
232-
return referenceClass.getClassLoader().loadClass( className );
232+
Class<?> result = referenceClass.getClassLoader().loadClass(className);
233+
if ( result.getClassLoader() == referenceClass.getClassLoader() ) {
234+
return result;
235+
}
233236
}
234237
catch (ClassNotFoundException e) {
235238
// Ignore

hibernate-core/src/main/java/org/hibernate/bytecode/internal/bytebuddy/BytecodeProviderImpl.java

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
import java.util.Collections;
1919
import java.util.List;
2020
import java.util.Map;
21-
import java.util.concurrent.Callable;
2221

2322
import org.hibernate.HibernateException;
2423
import org.hibernate.bytecode.enhance.internal.bytebuddy.EnhancerClassLocator;
@@ -184,7 +183,7 @@ public ReflectionOptimizer getReflectionOptimizer(
184183
.method( setPropertyValuesMethodName )
185184
.intercept( new Implementation.Simple( new SetPropertyValues( clazz, getterNames, setters ) ) )
186185
.method( getPropertyNamesMethodName )
187-
.intercept( MethodCall.call( new CloningPropertyCall( getterNames ) ) )
186+
.intercept( new Implementation.Simple( new GetPropertyNames( getterNames ) ) )
188187
);
189188

190189
try {
@@ -253,7 +252,7 @@ public ReflectionOptimizer getReflectionOptimizer(
253252
.method( setPropertyValuesMethodName )
254253
.intercept( new Implementation.Simple( new SetPropertyValues( clazz, propertyNames, setters ) ) )
255254
.method( getPropertyNamesMethodName )
256-
.intercept( MethodCall.call( new CloningPropertyCall( propertyNames ) ) )
255+
.intercept( new Implementation.Simple( new GetPropertyNames( propertyNames ) ) )
257256
);
258257
}
259258
else {
@@ -266,7 +265,7 @@ public ReflectionOptimizer getReflectionOptimizer(
266265
.method( setPropertyValuesMethodName )
267266
.intercept( new Implementation.Simple( new SetPropertyValues( clazz, propertyNames, setters ) ) )
268267
.method( getPropertyNamesMethodName )
269-
.intercept( MethodCall.call( new CloningPropertyCall( propertyNames ) ) )
268+
.intercept( new Implementation.Simple( new GetPropertyNames( propertyNames ) ) )
270269
);
271270
}
272271

@@ -887,17 +886,17 @@ public Size apply(
887886
Label nextLabel = new Label();
888887
for ( int index = 0; index < setters.length; index++ ) {
889888
final Member setterMember = setters[index];
890-
if ( enhanced && currentLabel != null ) {
889+
if ( setterMember == EMBEDDED_MEMBER ) {
890+
// The embedded property access does a no-op
891+
continue;
892+
}
893+
if ( currentLabel != null ) {
891894
methodVisitor.visitLabel( currentLabel );
892895
implementationContext.getFrameGeneration().same(
893896
methodVisitor,
894897
instrumentedMethod.getParameters().asTypeList()
895898
);
896899
}
897-
if ( setterMember == EMBEDDED_MEMBER ) {
898-
// The embedded property access does a no-op
899-
continue;
900-
}
901900
// Push entity on stack
902901
methodVisitor.visitVarInsn( Opcodes.ALOAD, 1 );
903902
methodVisitor.visitTypeInsn( Opcodes.CHECKCAST, Type.getInternalName( clazz ) );
@@ -1029,6 +1028,7 @@ else if ( setterMember instanceof Field ) {
10291028
}
10301029
if ( enhanced ) {
10311030
final boolean compositeTracker = CompositeTracker.class.isAssignableFrom( type );
1031+
boolean alreadyHasFrame = false;
10321032
// The composite owner check and setting only makes sense if
10331033
// * the value type is a composite tracker
10341034
// * a value subtype can be a composite tracker
@@ -1110,6 +1110,7 @@ else if ( setterMember instanceof Field ) {
11101110
// Clean stack after the if block
11111111
methodVisitor.visitLabel( compositeTrackerEndLabel );
11121112
implementationContext.getFrameGeneration().same(methodVisitor, instrumentedMethod.getParameters().asTypeList());
1113+
alreadyHasFrame = true;
11131114
}
11141115
if ( persistentAttributeInterceptable ) {
11151116
// Load the owner
@@ -1174,9 +1175,20 @@ else if ( setterMember instanceof Field ) {
11741175
// Clean stack after the if block
11751176
methodVisitor.visitLabel( instanceofEndLabel );
11761177
implementationContext.getFrameGeneration().same(methodVisitor, instrumentedMethod.getParameters().asTypeList());
1178+
alreadyHasFrame = true;
11771179
}
11781180

1179-
currentLabel = nextLabel;
1181+
if ( alreadyHasFrame ) {
1182+
// Usually, the currentLabel is visited as well generating a frame,
1183+
// but if a frame was already generated, only visit the label here,
1184+
// otherwise two frames for the same bytecode index are generated,
1185+
// which is wrong and will produce an error when the JDK ClassFile API is used
1186+
methodVisitor.visitLabel( nextLabel );
1187+
currentLabel = null;
1188+
}
1189+
else {
1190+
currentLabel = nextLabel;
1191+
}
11801192
nextLabel = new Label();
11811193
}
11821194
}
@@ -1346,17 +1358,29 @@ private static Constructor<?> findConstructor(Class<?> clazz) {
13461358
}
13471359
}
13481360

1349-
public static class CloningPropertyCall implements Callable<String[]> {
1361+
public static class GetPropertyNames implements ByteCodeAppender {
13501362

13511363
private final String[] propertyNames;
13521364

1353-
private CloningPropertyCall(String[] propertyNames) {
1365+
private GetPropertyNames(String[] propertyNames) {
13541366
this.propertyNames = propertyNames;
13551367
}
13561368

13571369
@Override
1358-
public String[] call() {
1359-
return propertyNames.clone();
1370+
public Size apply(
1371+
MethodVisitor methodVisitor,
1372+
Implementation.Context implementationContext,
1373+
MethodDescription instrumentedMethod) {
1374+
methodVisitor.visitLdcInsn( propertyNames.length );
1375+
methodVisitor.visitTypeInsn( Opcodes.ANEWARRAY, Type.getInternalName( String.class ) );
1376+
for ( int i = 0; i < propertyNames.length; i++ ) {
1377+
methodVisitor.visitInsn( Opcodes.DUP );
1378+
methodVisitor.visitLdcInsn( i );
1379+
methodVisitor.visitLdcInsn( propertyNames[i] );
1380+
methodVisitor.visitInsn( Opcodes.AASTORE );
1381+
}
1382+
methodVisitor.visitInsn( Opcodes.ARETURN );
1383+
return new Size( 4, instrumentedMethod.getStackSize() + 1 );
13601384
}
13611385
}
13621386

hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5774,4 +5774,26 @@ public FunctionalDependencyAnalysisSupport getFunctionalDependencyAnalysisSuppor
57745774
return FunctionalDependencyAnalysisSupportImpl.NONE;
57755775
}
57765776

5777+
/**
5778+
* Does this dialect support binding {@link Types#NULL} for {@link PreparedStatement#setNull(int, int)}?
5779+
* if it does, then call of {@link PreparedStatement#getParameterMetaData()} could be eliminated for better performance.
5780+
*
5781+
* @return {@code true} indicates it does; {@code false} indicates it does not;
5782+
* @see org.hibernate.type.descriptor.jdbc.ObjectNullResolvingJdbcType
5783+
*/
5784+
public boolean supportsBindingNullSqlTypeForSetNull() {
5785+
return false;
5786+
}
5787+
5788+
/**
5789+
* Does this dialect support binding {@code null} for {@link PreparedStatement#setObject(int, Object)}?
5790+
* if it does, then call of {@link PreparedStatement#getParameterMetaData()} could be eliminated for better performance.
5791+
*
5792+
* @return {@code true} indicates it does; {@code false} indicates it does not;
5793+
* @see org.hibernate.type.descriptor.jdbc.ObjectNullResolvingJdbcType
5794+
*/
5795+
public boolean supportsBindingNullForSetObject() {
5796+
return false;
5797+
}
5798+
57775799
}

hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,4 +1028,9 @@ public String getDual() {
10281028
return "dual";
10291029
}
10301030

1031+
@Override
1032+
public boolean supportsBindingNullSqlTypeForSetNull() {
1033+
return true;
1034+
}
1035+
10311036
}

0 commit comments

Comments
 (0)