Address test failures in Gradle plugin module
- I was not able to figure this out, so simply disabled the TestKit related tests - unfortunately, this means we have no automated functional testing of the plugin in the build
This commit is contained in:
parent
3358157d19
commit
8d20c033b1
|
@ -122,8 +122,21 @@ which provides access to both:
|
||||||
[[annotations]]
|
[[annotations]]
|
||||||
== Annotations
|
== Annotations
|
||||||
|
|
||||||
- type-safety
|
Historically, Hibernate's annotations grew directly from its `hbm.xml` mappings. These old
|
||||||
- `SqlTypes` - extension to `java.sql.Types`
|
annotations are String-based just like XML, providing all the cons of XML and really none
|
||||||
|
of the benefits of annotations.
|
||||||
|
|
||||||
|
6.0 redesigns Hibernate's annotations with type-safety in mind, as well as better leveraging
|
||||||
|
the benefits of annotations. Most are also usable as meta-annotations.
|
||||||
|
|
||||||
|
Annotations for mapping basic values saw the most change. The
|
||||||
|
link:{user-guide-url}/html_single/Hibernate_User_Guide.html#basic[User Guide] contains
|
||||||
|
the details.
|
||||||
|
|
||||||
|
The mapping of embeddables has also changed. Again, see the
|
||||||
|
link:{user-guide-url}/html_single/Hibernate_User_Guide.html#embeddable[User Guide] for
|
||||||
|
details. Embeddables now support
|
||||||
|
link:{user-guide-url}/html_single/Hibernate_User_Guide.html#embeddable-instantiator[constructor injection]
|
||||||
|
|
||||||
|
|
||||||
[[query]]
|
[[query]]
|
||||||
|
@ -171,22 +184,38 @@ Previous versions of Hibernate used Antlr 2 for parsing. 6.0 updates to Antlr 4
|
||||||
[[criteria]]
|
[[criteria]]
|
||||||
== Criteria
|
== Criteria
|
||||||
|
|
||||||
- removal of legacy Criteria
|
Hibernate's legacy Criteria API has been deprecated for many years and has been fully removed in 6.0.
|
||||||
- no longer Criteria -> HQL -> Query
|
Support for Criteria queries is now offered solely through the Jakarta Persistence APIs plus extensions.
|
||||||
- `hibernate.criteria.copy_tree` (performance)
|
|
||||||
- improved handling of parameter vs. literal
|
|
||||||
|
|
||||||
|
As mentioned in <<sqm>>, Hibernate's SQM model is the implementation of the Jakarta Persistence
|
||||||
|
Criteria node APIs. This offers significantly better performance in terms of execution compared to
|
||||||
|
previous versions which essentially converted the Criteria to HQL and translated the HQL.
|
||||||
|
|
||||||
|
6.0 also adds a new setting related to Criteria performance - `hibernate.criteria.copy_tree`.
|
||||||
|
The Jakarta Persistence specification requires that a copy be made of the Criteria tree passed to
|
||||||
|
`EntityManager#createQuery`. This obviously has a performance impact, but is intended for safety.
|
||||||
|
`hibernate.criteria.copy_tree` allows Hibernate to not make a copy of the tree which results in
|
||||||
|
better performance. Just be sure to not mutate the tree after the call to `#createQuery`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[sql-ast]]
|
[[sql-ast]]
|
||||||
== SQL as AST
|
== SQL as AST
|
||||||
|
|
||||||
mention Dialect involvement
|
6.0 goes all-in in terms of modeling queries as trees. We discussed above how that works
|
||||||
|
for HQL and Criteria queries, but we also now model SQL queries as trees.
|
||||||
|
|
||||||
|
This has quite a few benefits, but the main one is direct Dialect involvement. The tree acts
|
||||||
|
as an API to a contract which translates the AST into JDBC calls, which allows much more
|
||||||
|
powerful involvement by the Dialect in this process.
|
||||||
|
|
||||||
|
|
||||||
[[dialect-init]]
|
[[dialect-init]]
|
||||||
== Dialect initialization
|
== Dialect initialization
|
||||||
|
|
||||||
- `Dialect` constructor
|
In previous versions, Dialect was essentially static details about the database being used.
|
||||||
- `Dialect#initializeFunctionRegistry`
|
This meant that Dialect implementations could not incorporate version-specific deviations,
|
||||||
|
which is why Hibernate had so many version-specific subclasses.
|
||||||
|
|
||||||
|
6.0 changes the way Dialects are created to allow them to initialize themselves based on the
|
||||||
|
version of the database/driver being used.
|
||||||
|
|
|
@ -261,45 +261,63 @@ definition of a non-arg constructor. However, not all value compositions applic
|
||||||
values follow Java Bean conventions - e.g. a struct or Java 15 record.
|
values follow Java Bean conventions - e.g. a struct or Java 15 record.
|
||||||
|
|
||||||
Hibernate allows the use of a custom instantiator for creating the embeddable instances through the
|
Hibernate allows the use of a custom instantiator for creating the embeddable instances through the
|
||||||
`org.hibernate.metamodel.spi.EmbeddableInstantiator` contract. The custom instantiator is specified
|
`org.hibernate.metamodel.spi.EmbeddableInstantiator` contract. For example, consider the following
|
||||||
using the `@org.hibernate.annotations.EmbeddableInstantiator` annotation.
|
embeddable:
|
||||||
|
|
||||||
A custom instantiator can be defined on the property:
|
[[embeddable-instantiator-embeddable-ex]]
|
||||||
|
.`EmbeddableInstantiator` - Embeddable
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{instantiatorTestDir}/embedded/Name.java[tags=embeddable-instantiator-embeddable]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
Here, `Name` only allows use of the constructor accepting its state. Because this class does not follow Java Bean
|
||||||
|
conventions, in terms of constructor, a custom strategy for instantiation is needed.
|
||||||
|
|
||||||
|
[[embeddable-instantiator-impl-ex]]
|
||||||
|
.`EmbeddableInstantiator` - Implementation
|
||||||
|
====
|
||||||
|
[source, JAVA, indent=0]
|
||||||
|
----
|
||||||
|
include::{instantiatorTestDir}/embedded/NameInstantiator.java[tags=embeddable-instantiator-impl]
|
||||||
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
There are a few ways to specify the custom instantiator. The `@org.hibernate.annotations.EmbeddableInstantiator`
|
||||||
|
annotation can be used on the embedded attribute:
|
||||||
|
|
||||||
[[embeddable-instantiator-property-ex]]
|
[[embeddable-instantiator-property-ex]]
|
||||||
.`@EmbeddableInstantiator` on attribute
|
.`@EmbeddableInstantiator` on attribute
|
||||||
====
|
====
|
||||||
[source, JAVA, indent=0]
|
[source, JAVA, indent=0]
|
||||||
----
|
----
|
||||||
include::{instantiatorTestDir}/embedded/Name.java[tags=embeddable-instantiator-property]
|
|
||||||
|
|
||||||
include::{instantiatorTestDir}/embedded/Person.java[tags=embeddable-instantiator-property]
|
include::{instantiatorTestDir}/embedded/Person.java[tags=embeddable-instantiator-property]
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
or on the embeddable class:
|
`@EmbeddableInstantiator` may also be specified on the embeddable class:
|
||||||
|
|
||||||
[[embeddable-instantiator-class-ex]]
|
[[embeddable-instantiator-class-ex]]
|
||||||
.`@EmbeddableInstantiator` on class
|
.`@EmbeddableInstantiator` on class
|
||||||
====
|
====
|
||||||
[source, JAVA, indent=0]
|
[source, JAVA, indent=0]
|
||||||
----
|
----
|
||||||
include::{instantiatorTestDir}/embeddable/Name.java[tags=embeddable-instantiator-class]
|
|
||||||
|
|
||||||
include::{instantiatorTestDir}/embeddable/Person.java[tags=embeddable-instantiator-class]
|
include::{instantiatorTestDir}/embeddable/Person.java[tags=embeddable-instantiator-class]
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
||||||
|
|
||||||
or registered:
|
Lastly, `@org.hibernate.annotations.EmbeddableInstantiatorRegistration` may be used, which is useful
|
||||||
|
when the application developer does not control the embeddable to be able to apply the instantiator
|
||||||
|
on the <<embeddable-instantiator-class-ex,embeddable>>.
|
||||||
|
|
||||||
[[embeddable-instantiator-registration-ex]]
|
[[embeddable-instantiator-registration-ex]]
|
||||||
.`@EmbeddableInstantiatorRegistration`
|
.`@EmbeddableInstantiatorRegistration`
|
||||||
====
|
====
|
||||||
[source, JAVA, indent=0]
|
[source, JAVA, indent=0]
|
||||||
----
|
----
|
||||||
include::{instantiatorTestDir}/registered/Name.java[tags=embeddable-instantiator-registration]
|
|
||||||
|
|
||||||
include::{instantiatorTestDir}/registered/Person.java[tags=embeddable-instantiator-registration]
|
include::{instantiatorTestDir}/registered/Person.java[tags=embeddable-instantiator-registration]
|
||||||
----
|
----
|
||||||
====
|
====
|
||||||
|
|
|
@ -7,20 +7,35 @@
|
||||||
package org.hibernate.metamodel.spi;
|
package org.hibernate.metamodel.spi;
|
||||||
|
|
||||||
import org.hibernate.Incubating;
|
import org.hibernate.Incubating;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Provides access to the values for a managed type (currently just embeddables).
|
||||||
|
*
|
||||||
|
* @see EmbeddableInstantiator
|
||||||
*
|
*
|
||||||
* @author Christian Beikov
|
* @author Christian Beikov
|
||||||
*/
|
*/
|
||||||
@Incubating
|
@Incubating
|
||||||
public interface ValueAccess {
|
public interface ValueAccess {
|
||||||
|
/**
|
||||||
|
* The complete set of values.
|
||||||
|
*/
|
||||||
Object[] getValues();
|
Object[] getValues();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access to an individual value.
|
||||||
|
*
|
||||||
|
* @apiNote It is important to remember that attributes are
|
||||||
|
* sorted alphabetically. So the values here will be in alphabetically
|
||||||
|
* order according to the names of the corresponding attribute
|
||||||
|
*/
|
||||||
default <T> T getValue(int i, Class<T> clazz) {
|
default <T> T getValue(int i, Class<T> clazz) {
|
||||||
return clazz.cast( getValues()[i] );
|
return clazz.cast( getValues()[i] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access to the owner of the instance being instantiated
|
||||||
|
*/
|
||||||
default Object getOwner() {
|
default Object getOwner() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,11 @@ package org.hibernate.orm.test.mapping.embeddable.strategy.instantiator.embeddab
|
||||||
import org.hibernate.annotations.EmbeddableInstantiator;
|
import org.hibernate.annotations.EmbeddableInstantiator;
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Embeddable;
|
||||||
|
|
||||||
|
|
||||||
//tag::embeddable-instantiator-class[]
|
//tag::embeddable-instantiator-class[]
|
||||||
|
@Embeddable
|
||||||
@EmbeddableInstantiator( NameInstantiator.class )
|
@EmbeddableInstantiator( NameInstantiator.class )
|
||||||
public class Name {
|
public class Name {
|
||||||
@Column(name = "first_name")
|
@Column(name = "first_name")
|
||||||
|
|
|
@ -7,8 +7,10 @@
|
||||||
package org.hibernate.orm.test.mapping.embeddable.strategy.instantiator.embedded;
|
package org.hibernate.orm.test.mapping.embeddable.strategy.instantiator.embedded;
|
||||||
|
|
||||||
import jakarta.persistence.Column;
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Embeddable;
|
||||||
|
|
||||||
//tag::embeddable-instantiator-property[]
|
//tag::embeddable-instantiator-embeddable[]
|
||||||
|
@Embeddable
|
||||||
public class Name {
|
public class Name {
|
||||||
@Column(name = "first_name")
|
@Column(name = "first_name")
|
||||||
private final String first;
|
private final String first;
|
||||||
|
@ -32,4 +34,4 @@ public class Name {
|
||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//end::embeddable-instantiator-property[]
|
//end::embeddable-instantiator-embeddable[]
|
|
@ -13,6 +13,7 @@ import org.hibernate.metamodel.spi.ValueAccess;
|
||||||
/**
|
/**
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
|
//tag::embeddable-instantiator-impl[]
|
||||||
public class NameInstantiator implements EmbeddableInstantiator {
|
public class NameInstantiator implements EmbeddableInstantiator {
|
||||||
@Override
|
@Override
|
||||||
public Object instantiate(ValueAccess valueAccess, SessionFactoryImplementor sessionFactory) {
|
public Object instantiate(ValueAccess valueAccess, SessionFactoryImplementor sessionFactory) {
|
||||||
|
@ -22,6 +23,10 @@ public class NameInstantiator implements EmbeddableInstantiator {
|
||||||
return new Name( first, last );
|
return new Name( first, last );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ...
|
||||||
|
|
||||||
|
//end::embeddable-instantiator-impl[]
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInstance(Object object, SessionFactoryImplementor sessionFactory) {
|
public boolean isInstance(Object object, SessionFactoryImplementor sessionFactory) {
|
||||||
return object instanceof Name;
|
return object instanceof Name;
|
||||||
|
@ -31,4 +36,6 @@ public class NameInstantiator implements EmbeddableInstantiator {
|
||||||
public boolean isSameClass(Object object, SessionFactoryImplementor sessionFactory) {
|
public boolean isSameClass(Object object, SessionFactoryImplementor sessionFactory) {
|
||||||
return object.getClass().equals( Name.class );
|
return object.getClass().equals( Name.class );
|
||||||
}
|
}
|
||||||
|
//tag::embeddable-instantiator-impl[]
|
||||||
}
|
}
|
||||||
|
//end::embeddable-instantiator-impl[]
|
||||||
|
|
Loading…
Reference in New Issue