From 9028adc30e9ca79e46074890b4d8d7c3b0edf926 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Mon, 6 Dec 2021 10:12:25 -0600 Subject: [PATCH 1/4] Clean up test logging (hibernate-core) --- .../src/test/resources/log4j2.properties | 85 ++++++++++++------- .../testing/junit4/TestClassMetadata.java | 8 +- .../orm/UnclosedFixtureResourcesLogging.java | 13 +++ 3 files changed, 69 insertions(+), 37 deletions(-) create mode 100644 hibernate-testing/src/main/java/org/hibernate/testing/orm/UnclosedFixtureResourcesLogging.java diff --git a/hibernate-core/src/test/resources/log4j2.properties b/hibernate-core/src/test/resources/log4j2.properties index baafeccbcd..497d39ace7 100644 --- a/hibernate-core/src/test/resources/log4j2.properties +++ b/hibernate-core/src/test/resources/log4j2.properties @@ -3,66 +3,77 @@ # # License: GNU Lesser General Public License (LGPL), version 2.1 or later. # See the lgpl.txt file in the root directory or . -# -appender.stdout.type=Console + +# Normal STDOUT appender appender.stdout.name=STDOUT +appender.stdout.type=Console appender.stdout.layout.type=PatternLayout appender.stdout.layout.pattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n -appender.unclosedSessionFactoryFile.type=File -appender.unclosedSessionFactoryFile.name=unclosedSessionFactoryFile -appender.unclosedSessionFactoryFile.append=true -appender.unclosedSessionFactoryFile.fileName=target/tmp/log/UnclosedSessionFactoryWarnings.log -appender.unclosedSessionFactoryFile.layout.type=PatternLayout -appender.unclosedSessionFactoryFile.layout.pattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n - -appender.ddl.type=Console -appender.ddl.name=DDL -appender.ddl.layout.type=PatternLayout -appender.ddl.layout.pattern=%d{ABSOLUTE} %5p %c:%L - %m%n +appender.subsystem.name=subsystem +appender.subsystem.type=Console +appender.subsystem.layout.type=PatternLayout +appender.subsystem.layout.pattern=%d{ABSOLUTE} %5p %15.25c{5} %C{1}:%L - %m%n rootLogger.level=info rootLogger.appenderRef.stdout.ref=STDOUT +# SQL Logging - HHH-6833 +logger.sql.name=org.hibernate.SQL +logger.sql.level=debug + + +############################################################################### +# sub-system based logging + +logger.jdbc-bind.name=org.hibernate.orm.jdbc.bind +logger.jdbc-bind.appenderRef.subsystem.ref=subsystem +logger.jdbc-bind.level=trace + +logger.jdbc-extract.name=org.hibernate.orm.jdbc.extract +logger.jdbc-extract.appenderRef.subsystem.ref=subsystem +logger.jdbc-extract.level=trace + logger.graph.name=org.hibernate.orm.graph logger.graph.level=debug +logger.graph.appenderRef.subsystem.ref=subsystem ## Hibernate's JUnit extensions (hibernate-testing) ## - set to DEBUG or TRACE to see additional details ## from those extensions logger.junit.name=org.hibernate.testing.orm.junit +logger.junit.appenderRef.subsystem.ref=subsystem #logger.junit.level=debug logger.tooling-schema-script.name=org.hibernate.orm.tooling.schema.script +logger.tooling-schema-script.appenderRef.subsystem.ref=subsystem #logger.tooling-schema-script.level=trace + logger.tooling-schema-script-graph.name=org.hibernate.orm.tooling.schema.script.graph +logger.tooling-schema-script-graph.appenderRef.subsystem.ref=subsystem #logger.tooling-schema-script-graph.level=trace + +logger.sql-result-graph.name=org.hibernate.orm.sql.results +logger.sql-result-graph.appenderRef.subsystem.ref=subsystem +logger.sql-result-graph.level=debug + ## Logs every SQM tree logger.sqm-tree.name=org.hibernate.orm.query.sqm.ast +logger.sqm-tree.appenderRef.subsystem.ref=subsystem #logger.sqm-tree.level=debug + + +############################################################################### +# package/class name based logging + logger.hbm2ddl.name=org.hibernate.tool.hbm2ddl #logger.hbm2ddl.level=trace logger.testing-cache.name=org.hibernate.testing.cache #logger.testing-cache.level=debug -# SQL Logging - HHH-6833 -logger.sql.name=org.hibernate.SQL -logger.sql.level=debug - -logger.type-basic-binder.name=org.hibernate.type.descriptor.jdbc.BasicBinder -logger.type-basic-binder.level=trace -logger.type-basic-extractor.name=org.hibernate.type.descriptor.jdbc.BasicExtractor -logger.type-basic-extractor.level=trace - -logger.jdbc-bind.name=org.hibernate.orm.jdbc.bind -logger.jdbc-bind.level=trace - -logger.jdbc-extract.name=org.hibernate.orm.jdbc.extract -logger.jdbc-extract.level=trace - logger.hql-internal-ast.name=org.hibernate.hql.internal.ast logger.hql-internal-ast.level=debug @@ -99,9 +110,6 @@ logger.merged-entity-copies.name=org.hibernate.event.internal.EntityCopyAllowedL ### provide information about merged entity copies. #logger.merged-entity-copies.level=debug -logger.test-class-metadata.name=org.hibernate.testing.junit4.TestClassMetadata -logger.test-class-metadata.level=info -logger.test-class-metadata.appenderRef.unclosedSessionFactoryFile.ref=unclosedSessionFactoryFile logger.scanning-coordinator.name=org.hibernate.boot.model.process.internal.ScanningCoordinator logger.scanning-coordinator.level=debug logger.abstract-persistent-collection.name=org.hibernate.collection.internal.AbstractPersistentCollection @@ -110,4 +118,17 @@ logger.abstract-persistent-collection.level=debug logger.cache.name=org.hibernate.cache logger.cache.level=trace logger.stat.name=org.hibernate.stat -logger.stat.level=trace \ No newline at end of file +logger.stat.level=trace + + +# Specialized handling for tracking unclosed Session/SessionFactory resources as part of testing +appender.unclosedSessionFactoryFile.type=File +appender.unclosedSessionFactoryFile.name=unclosedSessionFactoryFile +appender.unclosedSessionFactoryFile.append=true +appender.unclosedSessionFactoryFile.fileName=target/tmp/log/UnclosedSessionFactoryWarnings.log +appender.unclosedSessionFactoryFile.layout.type=PatternLayout +appender.unclosedSessionFactoryFile.layout.pattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n + +logger.unclosedTestFixtures.name=org.hibernate.orm.testing.resources +logger.unclosedTestFixtures.level=info +logger.unclosedTestFixtures.appenderRef.unclosedSessionFactoryFile.ref=unclosedSessionFactoryFile diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/junit4/TestClassMetadata.java b/hibernate-testing/src/main/java/org/hibernate/testing/junit4/TestClassMetadata.java index a02603cb2f..1ae5a5892d 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/junit4/TestClassMetadata.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/junit4/TestClassMetadata.java @@ -20,6 +20,7 @@ import org.hibernate.testing.AfterClassOnce; import org.hibernate.testing.BeforeClassOnce; import org.hibernate.testing.OnExpectedFailure; import org.hibernate.testing.OnFailure; +import org.hibernate.testing.orm.UnclosedFixtureResourcesLogging; import org.jboss.logging.Logger; @@ -29,9 +30,6 @@ import org.jboss.logging.Logger; * @author Steve Ebersole */ public class TestClassMetadata { - - private static final Logger log = Logger.getLogger( TestClassMetadata.class ); - private static final Object[] NO_ARGS = new Object[0]; private final Class testClass; @@ -170,7 +168,7 @@ public class TestClassMetadata { public void performBeforeClassCallbacks(Object target) { if ( SessionFactoryRegistry.INSTANCE.hasRegistrations() ) { - log.warnf( "Open SessionFactory instances found prior to start of test class [%s]", testClass.getName() ); + UnclosedFixtureResourcesLogging.LOGGER.warnf( "Open SessionFactory instances found prior to start of test class [%s]", testClass.getName() ); } performCallbacks( beforeClassOnceMethods, target ); } @@ -215,7 +213,7 @@ public class TestClassMetadata { public void performAfterClassCallbacks(Object target) { performCallbacks( afterClassOnceMethods, target ); if ( SessionFactoryRegistry.INSTANCE.hasRegistrations() ) { - log.warnf( "Open SessionFactory instances found after completion of test class [%s]; closing them", testClass.getName() ); + UnclosedFixtureResourcesLogging.LOGGER.warnf( "Open SessionFactory instances found after completion of test class [%s]; closing them", testClass.getName() ); SessionFactoryRegistry.INSTANCE.clearRegistrations(); } } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/orm/UnclosedFixtureResourcesLogging.java b/hibernate-testing/src/main/java/org/hibernate/testing/orm/UnclosedFixtureResourcesLogging.java new file mode 100644 index 0000000000..9526ee1d41 --- /dev/null +++ b/hibernate-testing/src/main/java/org/hibernate/testing/orm/UnclosedFixtureResourcesLogging.java @@ -0,0 +1,13 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later + * See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html + */ +package org.hibernate.testing.orm; + +import org.jboss.logging.Logger; + +public class UnclosedFixtureResourcesLogging { + public static final Logger LOGGER = Logger.getLogger( "org.hibernate.orm.testing.resources" ); +} From bab32c310078e69e30c9267527d882fd263dd84c Mon Sep 17 00:00:00 2001 From: Christian Beikov Date: Mon, 6 Dec 2021 17:12:59 +0100 Subject: [PATCH 2/4] Small cleanup and add migration guide sections --- ...AbstractSingleColumnStandardBasicType.java | 2 +- .../type/AbstractStandardBasicType.java | 30 --------- .../org/hibernate/type/SingleColumnType.java | 65 ------------------- migration-guide.adoc | 65 +++++++++++++++++++ 4 files changed, 66 insertions(+), 96 deletions(-) delete mode 100644 hibernate-core/src/main/java/org/hibernate/type/SingleColumnType.java diff --git a/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java b/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java index 0691101c6f..b7c79a865e 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/AbstractSingleColumnStandardBasicType.java @@ -21,7 +21,7 @@ import org.hibernate.type.descriptor.jdbc.JdbcType; */ public abstract class AbstractSingleColumnStandardBasicType extends AbstractStandardBasicType - implements SingleColumnType { + implements Type { public AbstractSingleColumnStandardBasicType(JdbcType jdbcType, JavaType javaTypeDescriptor) { super( jdbcType, javaTypeDescriptor ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java index 350ac13b98..dcf0378b2b 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/AbstractStandardBasicType.java @@ -251,32 +251,6 @@ public abstract class AbstractStandardBasicType return isDirty( oldHydratedState, currentState ); } - private final Object nullSafeGet( - ResultSet rs, - String[] names, - SharedSessionContractImplementor session, - Object owner) throws SQLException { - return nullSafeGet( rs, names[0], session ); - } - - private final Object nullSafeGet(ResultSet rs, String name, SharedSessionContractImplementor session, Object owner) - throws SQLException { - return nullSafeGet( rs, name, session ); - } - - public final T nullSafeGet(ResultSet rs, String name, final SharedSessionContractImplementor session) throws SQLException { - return nullSafeGet( rs, name, (WrapperOptions) session ); - } - - protected final T nullSafeGet(ResultSet rs, String name, WrapperOptions options) throws SQLException { -// return remapSqlTypeDescriptor( options ).getExtractor( javaTypeDescriptor ).extract( rs, name, options ); - throw new UnsupportedOperationException( "Reading JDBC results by name/alias is no longer supported (" + getClass().getTypeName() + ")" ); - } - - public Object get(ResultSet rs, String name, SharedSessionContractImplementor session) throws HibernateException, SQLException { - return nullSafeGet( rs, name, session ); - } - @Override public final void nullSafeSet( PreparedStatement st, @@ -291,10 +265,6 @@ public abstract class AbstractStandardBasicType jdbcType.getBinder( javaTypeDescriptor ).bind( st, value, index, options ); } - public void set(PreparedStatement st, T value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException { - nullSafeSet( st, value, index, (WrapperOptions) session ); - } - @Override @SuppressWarnings({ "unchecked" }) public final String toLoggableString(Object value, SessionFactoryImplementor factory) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/SingleColumnType.java b/hibernate-core/src/main/java/org/hibernate/type/SingleColumnType.java deleted file mode 100644 index 208216359c..0000000000 --- a/hibernate-core/src/main/java/org/hibernate/type/SingleColumnType.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.type; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -import org.hibernate.HibernateException; -import org.hibernate.engine.spi.SharedSessionContractImplementor; - -/** - * Provide convenient methods for binding and extracting values for use with {@link BasicType}. - * - * @author Steve Ebersole - */ -public interface SingleColumnType extends Type { - - /** - * Get a column value from a result set by name. - * - * @param rs The result set from which to extract the value. - * @param name The name of the value to extract. - * @param session The session from which the request originates - * - * @return The extracted value. - * - * @throws HibernateException Generally some form of mismatch error. - * @throws SQLException Indicates problem making the JDBC call(s). - */ - T nullSafeGet(ResultSet rs, String name, SharedSessionContractImplementor session) throws HibernateException, SQLException; - - /** - * Get a column value from a result set, without worrying about the possibility of null values. - * - * @param rs The result set from which to extract the value. - * @param name The name of the value to extract. - * @param session The session from which the request originates - * - * @return The extracted value. - * - * @throws HibernateException Generally some form of mismatch error. - * @throws SQLException Indicates problem making the JDBC call(s). - */ - Object get(ResultSet rs, String name, SharedSessionContractImplementor session) throws HibernateException, SQLException; - - /** - * Set a parameter value without worrying about the possibility of null - * values. Called from {@link #nullSafeSet} after nullness checks have - * been performed. - * - * @param st The statement into which to bind the parameter value. - * @param value The parameter value to bind. - * @param index The position or index at which to bind the param value. - * @param session The session from which the request originates - * - * @throws HibernateException Generally some form of mismatch error. - * @throws SQLException Indicates problem making the JDBC call(s). - */ - void set(PreparedStatement st, T value, int index, SharedSessionContractImplementor session) throws HibernateException, SQLException; -} diff --git a/migration-guide.adoc b/migration-guide.adoc index 5e328fe4bb..ba11dee5ce 100644 --- a/migration-guide.adoc +++ b/migration-guide.adoc @@ -296,3 +296,68 @@ JOIN Node.node3.node2.node1 as you can see, this leads to a lot of joins very quickly, but the behavior of 5.x simply was not intuitive. To avoid creating so many joins, and also in general, we recommend that you use lazy fetching i.e. `@ManyToOne(fetch = FetchType.LAZY)` or `@OneToOne(fetch = FetchType.LAZY)` for most associations, but this is especially important if you have multiple self-referencing associations as you can see in the example. + +=== Removal of legacy Hibernate Criteria API + +The legacy Hibernate Criteria API which was deprecated back in Hibernate 5.x was removed in 6.0. +Usually, all queries using the legacy API can be modeled with the JPA Criteria API. +In some cases it is necessary to use the Hibernate JPA Criteria extensions. + +=== Removal of loader walkers + +The special walkers/visitors in the loader package were removed. This is now all controlled through `LoaderSelectBuilder`. + +=== Restructuring of the loader package + +The contents of the `loader.collection` package were restructured into `loader.ast.spi` and `loader.ast.internal` +as well as adapted to the SQM API. + +The contents of `loader.custom` were adapted and moved to `query.sql`. + +The contents of `loader.entity` and `loader.plan` were removed as that is now handled through `LoaderSelectBuilder`. + +=== Restructuring of the sql package + +The contents of `sql.ordering` were adapted and moved to `metamodel.mapping.ordering.ast`. + +Classes of the `sql` package that were previously used for building SQL, but aren't needed anymore, were removed. +The SQL generation is now fully handled through the `SqlAstTranslator` which a `Dialect` exposes a factory for. + +=== Changes in the type package + +One of the main changes in Hibernate 6 which ripples through quite a few contracts is the change for reading by position +rather than by name from JDBC. We took this as a chance to fix-up some contracts which were named badly and cleanup +basic types in general. + +==== Replace read-by-name with read-by-position + +Various contracts in `org.hibernate.type` and `org.hibernate.usertype` were changed to now offer a read-by-position +method. The read-by-name methods were removed. + +==== Removal of various BasicType implementations + +Almost all `BasicType` implementations in `org.hibernate.type` were removed because the responsibilities these classes +had were moved to the `JdbcType` and `JavaType` contracts as well as sub-contracts like `AdjustableJdbcType`, +`VersionJavaType` and `TemporalJavaTypeDescriptor`. + +The new implementation for almost all basic types is `NamedBasicTypeImpl` which just wraps a `JdbcType` and `JavaType` +along with a name. + +The `StandardBasicTypes` class previously exposed `BasicType` instance fields, which now have been replaced with fields +of the type `BasicTypeReference`. APIs that previously accepted just a `BasicType` have been adapted to also accept a +`BasicTypeReference` which allows for uses of `StandardBasicType` fields to stay mostly source compatible. + +==== Renaming of JavaTypeDescriptor contract + +Previously the package `org.hibernate.type.descriptor.java` contained `JavaTypeDescriptor` implementations +for various basic types named with a suffix of `Type`, `JavaType` or `JavaTypeDescriptor`. + +The `JavaTypeDescriptor` interface was renamed to `JavaType` and implementations were renamed to have the suffix `JavaType`. + +==== Renaming of SqlTypeDescriptor contract + +Previously the package `org.hibernate.type.descriptor.sql` contained `SqlTypeDescriptor` implementations +for various basic types named with a suffix of `TypeDescriptor`. + +The `SqlTypeDescriptor` interface was renamed to `JdbcType` and implementations were renamed to have the suffix `JdbcType`. +The package was also changed from `org.hibernate.type.descriptor.sql` to `org.hibernate.type.descriptor.jdbc`. From dc533b65cd049fdc9586304619ee488a8df84802 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Thu, 2 Dec 2021 10:50:31 +0000 Subject: [PATCH 3/4] Build: Upgrade Forbidden APIs to 3.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 13d0e2f557..c52b382985 100644 --- a/build.gradle +++ b/build.gradle @@ -15,7 +15,7 @@ buildscript { classpath 'gradle.plugin.com.github.lburgazzoli:gradle-karaf-plugin:0.5.1' classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.7' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' - classpath 'de.thetaphi:forbiddenapis:3.0.1' + classpath 'de.thetaphi:forbiddenapis:3.2' classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.1' } } From 6ecc19b64f42d9a34120b7cfe896feefc4521b65 Mon Sep 17 00:00:00 2001 From: Sanne Grinovero Date: Thu, 2 Dec 2021 10:51:06 +0000 Subject: [PATCH 4/4] Build: No longer needing gradle-karaf-plugin --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index c52b382985..994c318338 100644 --- a/build.gradle +++ b/build.gradle @@ -12,7 +12,6 @@ buildscript { dependencies { classpath 'org.hibernate.build.gradle:version-injection-plugin:1.0.0' - classpath 'gradle.plugin.com.github.lburgazzoli:gradle-karaf-plugin:0.5.1' classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.7' classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' classpath 'de.thetaphi:forbiddenapis:3.2'