HHH-18193 - Remove @Polymorphism

This commit is contained in:
Steve Ebersole 2024-07-23 16:24:10 -05:00
parent ea1f74407d
commit 44e802ebac
31 changed files with 54 additions and 923 deletions

View File

@ -314,69 +314,6 @@ include::{extrasdir}/entity-inheritance-table-per-class-query-example.sql[]
Polymorphic queries require multiple UNION queries, so be aware of the performance implications of a large class hierarchy.
====
[[entity-inheritance-polymorphism]]
==== Implicit and explicit polymorphism
By default, when you query a base class entity,
the polymorphic query will fetch all subclasses belonging to the base type.
However, you can even query
*interfaces or base classes that don't belong to the Jakarta Persistence entity inheritance model*.
For instance, considering the following `DomainModelEntity` interface:
[[entity-inheritance-polymorphism-interface-example]]
.DomainModelEntity interface
====
[source,java]
----
include::{example-dir-inheritance}/polymorphism/DomainModelEntity.java[tags=entity-inheritance-polymorphism-interface-example,indent=0]
----
====
If we have two entity mappings, a `Book` and a `Blog`,
and the `Blog` entity is mapped with the
https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Polymorphism.html[`@Polymorphism`] annotation
and taking the `PolymorphismType.EXPLICIT` setting:
[[entity-inheritance-polymorphism-mapping-example]]
.`@Polymorphism` entity mapping
====
[source,java]
----
include::{example-dir-inheritance}/polymorphism/ExplicitPolymorphismTest.java[tags=entity-inheritance-polymorphism-mapping-example,indent=0]
----
====
If we have the following entity objects in our system:
[[entity-inheritance-polymorphism-persist-example]]
.Domain Model entity objects
====
[source,java]
----
include::{example-dir-inheritance}/polymorphism/ExplicitPolymorphismTest.java[tags=entity-inheritance-polymorphism-persist-example,indent=0]
----
====
We can now query against the `DomainModelEntity` interface,
and Hibernate is going to fetch only the entities that are either mapped with
`@Polymorphism(type = PolymorphismType.IMPLICIT)`
or they are not annotated at all with the `@Polymorphism` annotation (implying the IMPLICIT behavior):
[[entity-inheritance-polymorphism-fetch-example]]
.Fetching Domain Model entities using non-mapped base class polymorphism
====
[source,java]
----
include::{example-dir-inheritance}/polymorphism/ExplicitPolymorphismTest.java[tags=entity-inheritance-polymorphism-fetch-example,indent=0]
----
====
Therefore, only the `Book` was fetched since the `Blog` entity was marked with the
`@Polymorphism(type = PolymorphismType.EXPLICIT)` annotation, which instructs Hibernate
to skip it when executing a polymorphic query against a non-mapped base class.
[[embeddable-inheritance]]
==== Embeddable inheritance

View File

@ -2109,9 +2109,6 @@ The query `from java.lang.Object` is completely legal. (But not very useful!)
It returns every object of every mapped entity type.
====
This behavior may be slightly adjusted using the `@Polymorphism` annotation.
See <<chapters/domain/inheritance.adoc#entity-inheritance-polymorphism>> for more.
[[hql-derived-root]]
==== Derived roots

View File

@ -1,64 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Allows <em>implicit polymorphism</em> to be disabled for
* an entity class hierarchy, by annotating the root entity
* {@code @Polymorphism(type=EXPLICIT)}.
* <p>
* Hibernate allows a query {@code from} clause to name a
* {@linkplain org.hibernate.mapping.MappedSuperclass
* mapped superclass}, or even an arbitrary Java type which
* is neither an entity class nor a mapped superclass. The
* query will return all entities which inherit the type.
* For example, the query
* <pre>from java.lang.Object</pre>
* <p>
* will return every entity mapped by Hibernate!
* <p>
* This can be thought of as allowing a sort of "poor man's"
* {@linkplain jakarta.persistence.InheritanceType#TABLE_PER_CLASS
* table per class} inheritance, though it comes with many
* limitations.
* <p>
* This annotation allows an entity class to refuse to
* participate in such a crazy query, so that it's never
* returned by any query that names one of its non-entity
* supertypes.
* <p>
* Note that this annotation may only be applied to the root
* entity in an entity inheritance hierarchy, and its effect
* is inherited by entity subclasses.
* <p>
* Note also that this has <em>no effect at all</em> on the
* usual polymorphism within a mapped entity class inheritance
* hierarchy, as defied by the JPA specification. "Implicit"
* polymorphism is about queries that span multiple such
* entity inheritance hierarchies.
*
* @deprecated This annotation is hardly ever useful.
*
* @author Steve Ebersole
*/
@Deprecated(since = "6.2")
@Target( TYPE )
@Retention( RUNTIME )
public @interface Polymorphism {
/**
* Determines whether implicit polymorphism is enabled
* or disabled for the annotated entity class. It is
* enabled by default.
*/
PolymorphismType type() default PolymorphismType.IMPLICIT;
}

View File

@ -1,55 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.annotations;
import java.util.Locale;
/**
* Specifies whether implicit polymorphism is enabled or disabled.
*
* @see Polymorphism
*
* @author Emmanuel Bernard
*
* @deprecated since {@link Polymorphism} is deprecated
*/
@Deprecated(since = "6.2")
public enum PolymorphismType {
/**
* Implicit polymorphism is enabled, and queries against mapped
* superclasses and other arbitrary Java supertypes of an entity
* will return instances of the entity.
*/
IMPLICIT,
/**
* Implicit polymorphism is disabled, and queries against mapped
* superclasses and other arbitrary Java supertypes of an entity
* will not return the entity.
*/
EXPLICIT;
public static PolymorphismType fromExternalValue(Object externalValue) {
if ( externalValue != null ) {
if ( externalValue instanceof PolymorphismType ) {
return (PolymorphismType) externalValue;
}
final String externalValueStr = externalValue.toString();
for ( PolymorphismType checkType : values() ) {
if ( checkType.name().equalsIgnoreCase( externalValueStr ) ) {
return checkType;
}
}
}
return null;
}
public String getExternalForm() {
return name().toLowerCase( Locale.ROOT );
}
}

View File

@ -19,7 +19,6 @@ import java.util.function.Consumer;
import org.hibernate.AssertionFailure;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.OnDeleteAction;
import org.hibernate.annotations.PolymorphismType;
import org.hibernate.boot.MappingException;
import org.hibernate.boot.internal.LimitedCollectionClassification;
import org.hibernate.boot.jaxb.Origin;
@ -80,7 +79,6 @@ import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmOnDeleteEnum;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmOneToManyCollectionElementType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmOneToOneType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmOuterJoinEnum;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmPolymorphismEnum;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmPrimitiveArrayType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmPropertiesType;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmQueryParamType;
@ -139,7 +137,6 @@ import org.hibernate.boot.jaxb.mapping.spi.JaxbGenericIdGeneratorImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbHqlImportImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbIdImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbInheritanceImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinColumnImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbJoinTableImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToManyImpl;
import org.hibernate.boot.jaxb.mapping.spi.JaxbManyToOneImpl;
@ -430,7 +427,6 @@ public class HbmXmlTransformer {
mappingEntity.setOptimisticLocking( hbmClass.getOptimisticLock() );
mappingEntity.setDiscriminatorValue( hbmClass.getDiscriminatorValue() );
mappingEntity.setPolymorphism( convert( hbmClass.getPolymorphism() ) );
transferDiscriminator( hbmClass, mappingEntity, entityInfo );
transferEntityAttributes( hbmClass, mappingEntity, entityInfo );
@ -1133,14 +1129,6 @@ public class HbmXmlTransformer {
throw new IllegalArgumentException( "Unrecognized cache-inclusions value : " + hbmInclusion );
}
@SuppressWarnings("deprecation")
private static PolymorphismType convert(JaxbHbmPolymorphismEnum polymorphism) {
if ( polymorphism == null ) {
return null;
}
return polymorphism == JaxbHbmPolymorphismEnum.EXPLICIT ? PolymorphismType.EXPLICIT : PolymorphismType.IMPLICIT;
}
private void transferResultSetMappings(String namePrefix, ResultSetMappingContainer container) {
final List<JaxbHbmResultSetMappingType> resultSetMappings = container.getResultset();
resultSetMappings.forEach( (hbmMapping) -> {

View File

@ -1,22 +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 http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.boot.jaxb.mapping.internal;
import org.hibernate.annotations.PolymorphismType;
/**
* @author Steve Ebersole
*/
public class PolymorphismTypeMarshalling {
public static PolymorphismType fromXml(String value) {
return value == null ? null : PolymorphismType.valueOf( value );
}
public static String toXml(PolymorphismType value) {
return value == null ? null : value.name();
}
}

View File

@ -8,7 +8,6 @@ package org.hibernate.boot.jaxb.mapping.spi;
import java.util.List;
import org.hibernate.annotations.PolymorphismType;
import org.hibernate.engine.OptimisticLockStyle;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -82,9 +81,6 @@ public interface JaxbEntity extends JaxbEntityOrMappedSuperclass {
@Nullable String getProxy();
void setProxy(@Nullable String value);
@Nullable PolymorphismType getPolymorphism();
void setPolymorphism(@Nullable PolymorphismType value);
@Nullable String getDiscriminatorValue();
void setDiscriminatorValue(@Nullable String value);

View File

@ -37,8 +37,6 @@ import org.hibernate.annotations.NaturalIdCache;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OptimisticLockType;
import org.hibernate.annotations.OptimisticLocking;
import org.hibernate.annotations.Polymorphism;
import org.hibernate.annotations.PolymorphismType;
import org.hibernate.annotations.Proxy;
import org.hibernate.annotations.QueryCacheLayout;
import org.hibernate.annotations.RowId;
@ -138,8 +136,6 @@ import jakarta.persistence.SharedCacheMode;
import jakarta.persistence.UniqueConstraint;
import static jakarta.persistence.InheritanceType.SINGLE_TABLE;
import static org.hibernate.annotations.PolymorphismType.EXPLICIT;
import static org.hibernate.annotations.PolymorphismType.IMPLICIT;
import static org.hibernate.boot.model.internal.AnnotatedClassType.MAPPED_SUPERCLASS;
import static org.hibernate.boot.model.internal.AnnotatedDiscriminatorColumn.DEFAULT_DISCRIMINATOR_COLUMN_NAME;
import static org.hibernate.boot.model.internal.AnnotatedDiscriminatorColumn.buildDiscriminatorColumn;
@ -186,7 +182,6 @@ public class EntityBinder {
private String name;
private ClassDetails annotatedClass;
private PersistentClass persistentClass;
private PolymorphismType polymorphismType;
private boolean lazy;
private ClassDetails proxyClass;
private String where;
@ -1293,11 +1288,6 @@ public class EntityBinder {
: optimisticLockingAnn.type() ) );
}
private void bindPolymorphism() {
final Polymorphism polymorphismAnn = annotatedClass.getAnnotationUsage( Polymorphism.class, getSourceModelContext() );
polymorphismType = polymorphismAnn == null ? IMPLICIT : polymorphismAnn.type();
}
private void bindEntityAnnotation() {
final Entity entity = annotatedClass.getAnnotationUsage( Entity.class, getSourceModelContext() );
if ( entity == null ) {
@ -1317,7 +1307,6 @@ public class EntityBinder {
bindEntityAnnotation();
bindRowManagement();
bindOptimisticLocking();
bindPolymorphism();
bindProxy();
bindConcreteProxy();
bindWhere();
@ -1379,7 +1368,6 @@ public class EntityBinder {
private void bindRootEntity() {
final RootClass rootClass = (RootClass) persistentClass;
rootClass.setMutable( isMutable() );
rootClass.setExplicitPolymorphism( polymorphismType == EXPLICIT );
if ( isNotEmpty( where ) ) {
rootClass.setWhere( where );
}

View File

@ -266,7 +266,10 @@ public class ModelBinder {
rootEntityDescriptor.setOptimisticLockStyle( hierarchySource.getOptimisticLockStyle() );
rootEntityDescriptor.setMutable( hierarchySource.isMutable() );
rootEntityDescriptor.setWhere( hierarchySource.getWhere() );
rootEntityDescriptor.setExplicitPolymorphism( hierarchySource.isExplicitPolymorphism() );
if ( hierarchySource.isExplicitPolymorphism() ) {
DEPRECATION_LOGGER.warn( "Implicit/explicit polymorphism no longer supported" );
}
bindEntityIdentifier(
mappingDocument,

View File

@ -488,10 +488,6 @@ public interface HibernateAnnotations {
PartitionKey.class,
PartitionKeyAnnotation.class
);
OrmAnnotationDescriptor<Polymorphism,PolymorphismAnnotation> POLYMORPHISM = new OrmAnnotationDescriptor<>(
Polymorphism.class,
PolymorphismAnnotation.class
);
OrmAnnotationDescriptor<Proxy,ProxyAnnotation> PROXY = new OrmAnnotationDescriptor<>(
Proxy.class,
ProxyAnnotation.class

View File

@ -1,60 +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 http://www.gnu.org/licenses/lgpl-2.1.html.
*/
package org.hibernate.boot.models.annotations.internal;
import java.lang.annotation.Annotation;
import org.hibernate.annotations.Polymorphism;
import org.hibernate.boot.models.HibernateAnnotations;
import org.hibernate.models.spi.SourceModelBuildingContext;
import org.jboss.jandex.AnnotationInstance;
import static org.hibernate.boot.models.internal.OrmAnnotationHelper.extractJandexValue;
@SuppressWarnings({ "ClassExplicitlyAnnotation", "unused" })
@jakarta.annotation.Generated("org.hibernate.orm.build.annotations.ClassGeneratorProcessor")
public class PolymorphismAnnotation implements Polymorphism {
private org.hibernate.annotations.PolymorphismType type;
/**
* Used in creating dynamic annotation instances (e.g. from XML)
*/
public PolymorphismAnnotation(SourceModelBuildingContext modelContext) {
this.type = org.hibernate.annotations.PolymorphismType.IMPLICIT;
}
/**
* Used in creating annotation instances from JDK variant
*/
public PolymorphismAnnotation(Polymorphism annotation, SourceModelBuildingContext modelContext) {
this.type = annotation.type();
}
/**
* Used in creating annotation instances from Jandex variant
*/
public PolymorphismAnnotation(AnnotationInstance annotation, SourceModelBuildingContext modelContext) {
this.type = extractJandexValue( annotation, HibernateAnnotations.POLYMORPHISM, "type", modelContext );
}
@Override
public Class<? extends Annotation> annotationType() {
return Polymorphism.class;
}
@Override
public org.hibernate.annotations.PolymorphismType type() {
return type;
}
public void type(org.hibernate.annotations.PolymorphismType value) {
this.type = value;
}
}

View File

@ -29,8 +29,8 @@ import org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle;
import org.hibernate.internal.FilterConfiguration;
import org.hibernate.internal.util.collections.JoinedList;
import org.hibernate.jdbc.Expectation;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.jpa.event.spi.CallbackDefinition;
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
import org.hibernate.query.sqm.function.SqmFunctionRegistry;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.sql.Alias;
@ -41,9 +41,9 @@ import org.hibernate.type.spi.TypeConfiguration;
import static java.util.Collections.emptyList;
import static java.util.Collections.unmodifiableList;
import static java.util.Comparator.comparing;
import static org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle.expectationConstructor;
import static org.hibernate.internal.util.StringHelper.qualify;
import static org.hibernate.internal.util.StringHelper.root;
import static org.hibernate.engine.spi.ExecuteUpdateResultCheckStyle.expectationConstructor;
import static org.hibernate.mapping.MappingHelper.checkPropertyColumnDuplication;
import static org.hibernate.sql.Template.collectColumnNames;
@ -342,7 +342,13 @@ public abstract class PersistentClass implements IdentifiableTypeClass, Attribut
public abstract PersistentClass getSuperclass();
public abstract boolean isExplicitPolymorphism();
/**
* @deprecated No longer supported
*/
@Deprecated
public boolean isExplicitPolymorphism() {
return false;
}
public abstract boolean isDiscriminatorInsertable();

View File

@ -47,7 +47,6 @@ public class RootClass extends PersistentClass implements TableOwner, SoftDeleta
private Value discriminator;
private boolean mutable = true;
private boolean embeddedIdentifier;
private boolean explicitPolymorphism;
private boolean forceDiscriminator;
private boolean concreteProxy;
private String where;
@ -124,6 +123,10 @@ public class RootClass extends PersistentClass implements TableOwner, SoftDeleta
return polymorphic;
}
/**
* @deprecated No longer supported
*/
@Deprecated
public void setPolymorphic(boolean polymorphic) {
this.polymorphic = polymorphic;
}
@ -154,11 +157,6 @@ public class RootClass extends PersistentClass implements TableOwner, SoftDeleta
setPolymorphic( true );
}
@Override
public boolean isExplicitPolymorphism() {
return explicitPolymorphism;
}
@Override
public Property getVersion() {
return version;
@ -215,8 +213,11 @@ public class RootClass extends PersistentClass implements TableOwner, SoftDeleta
this.embeddedIdentifier = embeddedIdentifier;
}
/**
* @deprecated No longer supported
*/
@Deprecated
public void setExplicitPolymorphism(boolean explicitPolymorphism) {
this.explicitPolymorphism = explicitPolymorphism;
}
public void setIdentifier(KeyValue identifier) {

View File

@ -191,11 +191,6 @@ public class Subclass extends PersistentClass {
return getSuperclass().getIdentifier();
}
@Override
public boolean isExplicitPolymorphism() {
return getSuperclass().isExplicitPolymorphism();
}
@Override
public boolean isConcreteProxy() {
return getRootClass().isConcreteProxy();

View File

@ -232,7 +232,10 @@ public interface EntityMappingType
/**
* Is this class explicit polymorphism only?
*
* @deprecated No longer supported
*/
@Deprecated
boolean isExplicitPolymorphism();
/**

View File

@ -562,28 +562,19 @@ public class JpaMetamodelImpl implements JpaMetamodelImplementor, Serializable {
// we should add it to the collecting set of matching descriptors. it should
// be added aside from a few cases...
// it should not be added if its direct super (if one) is defined without
// explicit-polymorphism. The super itself will get added and the initializers
// for entity mappings already handle loading subtypes - adding it would be redundant
// if the managed-type has a super type and the java type is assignable from the super type,
// do not add the managed-type as the super itself will get added and the initializers for
// entity mappings already handle loading subtypes - adding it would be redundant and lead to
// incorrect results
final ManagedDomainType<?> superType = managedType.getSuperType();
if ( superType != null
&& superType.getPersistenceType() == Type.PersistenceType.ENTITY
&& javaType.isAssignableFrom( superType.getJavaType() ) ) {
final EntityDomainType<?> domainType = (EntityDomainType<?>) superType;
final EntityMappingType superMapping = getMappingMetamodel()
.getEntityDescriptor( domainType.getHibernateEntityName() );
if ( !superMapping.isExplicitPolymorphism() ) {
continue;
}
continue;
}
// it should not be added if it is mapped with explicit polymorphism itself
final EntityMappingType entityPersister = getMappingMetamodel()
.getEntityDescriptor( managedType.getTypeName() );
if ( !entityPersister.isExplicitPolymorphism() ) {
// aside from these special cases, add it
matchingDescriptors.add( (EntityDomainType<? extends T>) managedType );
}
// otherwise, add it
matchingDescriptors.add( (EntityDomainType<? extends T>) managedType );
}
}

View File

@ -758,30 +758,23 @@ public class MappingMetamodelImpl extends QueryParameterBindingTypeResolverImpl
for ( EntityPersister checkPersister : entityPersisters().values() ) {
final String checkQueryableEntityName = ((EntityMappingType) checkPersister).getEntityName();
final boolean isMappedClass = clazz.getName().equals( checkQueryableEntityName );
if ( checkPersister.isExplicitPolymorphism() ) {
if ( isMappedClass ) {
return new String[] { clazz.getName() }; // NOTE EARLY EXIT
}
if ( isMappedClass ) {
results.add( checkQueryableEntityName );
}
else {
if ( isMappedClass ) {
results.add( checkQueryableEntityName );
}
else {
final Class<?> mappedClass = checkPersister.getMappedClass();
if ( mappedClass != null && clazz.isAssignableFrom( mappedClass ) ) {
final boolean assignableSuperclass;
if ( checkPersister.isInherited() ) {
final String superTypeName = checkPersister.getSuperMappingType().getEntityName();
final Class<?> mappedSuperclass = getEntityDescriptor( superTypeName ).getMappedClass();
assignableSuperclass = clazz.isAssignableFrom( mappedSuperclass );
}
else {
assignableSuperclass = false;
}
if ( !assignableSuperclass ) {
results.add( checkQueryableEntityName );
}
final Class<?> mappedClass = checkPersister.getMappedClass();
if ( mappedClass != null && clazz.isAssignableFrom( mappedClass ) ) {
final boolean assignableSuperclass;
if ( checkPersister.isInherited() ) {
final String superTypeName = checkPersister.getSuperMappingType().getEntityName();
final Class<?> mappedSuperclass = getEntityDescriptor( superTypeName ).getMappedClass();
assignableSuperclass = clazz.isAssignableFrom( mappedSuperclass );
}
else {
assignableSuperclass = false;
}
if ( !assignableSuperclass ) {
results.add( checkQueryableEntityName );
}
}
}

View File

@ -244,9 +244,8 @@ public class ResultSetMappingImpl implements ResultSetMapping {
// As people should be able to just run native queries and work with tuples
if ( resultBuilders != null ) {
final Set<String> knownDuplicateAliases = new TreeSet<>( String.CASE_INSENSITIVE_ORDER );
if ( resultBuilders.size() == 1 && domainResults.size() == 1 && domainResults.get( 0 ) instanceof EntityResult ) {
if ( resultBuilders.size() == 1 && domainResults.size() == 1 && domainResults.get( 0 ) instanceof EntityResult entityResult ) {
// Special case for result set mappings that just fetch a single polymorphic entity
final EntityResult entityResult = (EntityResult) domainResults.get( 0 );
final EntityPersister persister = entityResult.getReferencedMappingContainer().getEntityPersister();
final boolean polymorphic = persister.getEntityMetamodel().isPolymorphic();
// We only need to check for duplicate aliases if we have join fetches,

View File

@ -135,7 +135,6 @@ public class EntityMetamodel implements Serializable {
private final boolean polymorphic;
private final String superclass; // superclass entity-name
private final boolean explicitPolymorphism;
private final boolean inherited;
private final boolean hasSubclasses;
private final Set<String> subclassEntityNames;
@ -431,7 +430,6 @@ public class EntityMetamodel implements Serializable {
dynamicInsert = persistentClass.useDynamicInsert();
polymorphic = persistentClass.isPolymorphic();
explicitPolymorphism = persistentClass.isExplicitPolymorphism();
inherited = persistentClass.isInherited();
superclass = inherited ?
persistentClass.getSuperclass().getEntityName() :
@ -732,8 +730,12 @@ public class EntityMetamodel implements Serializable {
return superclass;
}
/**
* @deprecated No longer supported
*/
@Deprecated
public boolean isExplicitPolymorphism() {
return explicitPolymorphism;
return false;
}
public boolean isInherited() {

View File

@ -715,12 +715,6 @@
printMethod="org.hibernate.boot.jaxb.mapping.internal.OnDeleteActionMarshalling.toXml" />
</bindings>
<bindings node="//xsd:simpleType[@name='polymorphism-type']">
<javaType name="org.hibernate.annotations.PolymorphismType"
parseMethod="org.hibernate.boot.jaxb.mapping.internal.PolymorphismTypeMarshalling.fromXml"
printMethod="org.hibernate.boot.jaxb.mapping.internal.PolymorphismTypeMarshalling.toXml" />
</bindings>
<bindings node="//xsd:simpleType[@name='temporal-type']">
<javaType name="jakarta.persistence.TemporalType"
parseMethod="org.hibernate.boot.jaxb.mapping.internal.TemporalTypeMarshalling.fromXml"

View File

@ -193,31 +193,6 @@ public class BasicHibernateAnnotationsTest extends BaseCoreFunctionalTestCase {
s.close();
}
@Test
@RequiresDialectFeature( DialectChecks.SupportsExpectedLobUsagePattern.class )
public void testPolymorphism() throws Exception {
Forest forest = new Forest();
forest.setName( "Fontainebleau" );
forest.setLength( 33 );
Session s;
Transaction tx;
s = openSession();
tx = s.beginTransaction();
s.persist( forest );
tx.commit();
s.close();
s = openSession();
tx = s.beginTransaction();
Query query = s.createQuery( "from java.lang.Object" );
assertEquals( 0, query.list().size() );
query = s.createQuery( "from Forest" );
assertTrue( 0 < query.list().size() );
tx.commit();
s.close();
}
@Test
@RequiresDialectFeature( DialectChecks.SupportsExpectedLobUsagePattern.class )
public void testType() throws Exception {

View File

@ -11,8 +11,6 @@ package org.hibernate.orm.test.annotations.entity;
import java.sql.Types;
import java.util.Set;
import jakarta.persistence.Index;
import jakarta.persistence.Table;
import org.hibernate.annotations.BatchSize;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
@ -23,8 +21,6 @@ import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.OptimisticLockType;
import org.hibernate.annotations.OptimisticLocking;
import org.hibernate.annotations.ParamDef;
import org.hibernate.annotations.Polymorphism;
import org.hibernate.annotations.PolymorphismType;
import org.hibernate.annotations.SelectBeforeUpdate;
import org.hibernate.annotations.Where;
@ -33,7 +29,9 @@ import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Index;
import jakarta.persistence.Lob;
import jakarta.persistence.Table;
/**
* Use hibernate specific annotations
@ -45,7 +43,6 @@ import jakarta.persistence.Lob;
@SelectBeforeUpdate
@DynamicInsert @DynamicUpdate
@OptimisticLocking(type = OptimisticLockType.ALL)
@Polymorphism(type = PolymorphismType.EXPLICIT)
@Where(clause = "1=1")
@FilterDef(name = "minLength", parameters = {@ParamDef(name = "minLength", type = Integer.class)})
@Filter(name = "betweenLength")

View File

@ -1,69 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.annotations.entity;
import java.sql.Types;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.OptimisticLockType;
import org.hibernate.annotations.OptimisticLocking;
import org.hibernate.annotations.Polymorphism;
import org.hibernate.annotations.PolymorphismType;
import org.hibernate.annotations.SelectBeforeUpdate;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
/**
* Mapping following lines of {@link Forest}, but using the replacements for the now deprecated
* {@link jakarta.persistence.Entity} annotation.
*
* @author Steve Ebersole
*/
@Entity
@DynamicInsert
@DynamicUpdate
@SelectBeforeUpdate
@OptimisticLocking( type = OptimisticLockType.ALL )
@Polymorphism( type = PolymorphismType.EXPLICIT )
public class Forest2 {
private Integer id;
private String name;
private String longDescription;
@Id
@GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@OptimisticLock(excluded=true)
@JdbcTypeCode( Types.LONGVARCHAR )
public String getLongDescription() {
return longDescription;
}
public void setLongDescription(String longDescription) {
this.longDescription = longDescription;
}
}

View File

@ -1,58 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.annotations.entity;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.mapping.RootClass;
import org.hibernate.testing.AfterClassOnce;
import org.hibernate.testing.BeforeClassOnce;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.testing.util.ServiceRegistryUtil;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* @author Steve Ebersole
*/
public class NewCustomEntityMappingAnnotationsTest extends BaseUnitTestCase {
private StandardServiceRegistry ssr;
private Metadata metadata;
@BeforeClassOnce
public void setUp() {
ssr = ServiceRegistryUtil.serviceRegistry();
metadata = new MetadataSources( ssr )
.addAnnotatedClass( Forest.class )
.addAnnotatedClass( Forest2.class )
.addPackage( Forest.class.getPackage().getName() )
.buildMetadata();
}
@AfterClassOnce
public void tearDown() {
if ( ssr != null ) {
StandardServiceRegistryBuilder.destroy( ssr );
}
}
@Test
public void testSameMappingValues() {
RootClass forest = (RootClass) metadata.getEntityBinding( Forest.class.getName() );
RootClass forest2 = (RootClass) metadata.getEntityBinding( Forest2.class.getName() );
assertEquals( forest.useDynamicInsert(), forest2.useDynamicInsert() );
assertEquals( forest.useDynamicUpdate(), forest2.useDynamicUpdate() );
assertEquals( forest.hasSelectBeforeUpdate(), forest2.hasSelectBeforeUpdate() );
assertEquals( forest.getOptimisticLockStyle(), forest2.getOptimisticLockStyle() );
assertEquals( forest.isExplicitPolymorphism(), forest2.isExplicitPolymorphism() );
}
}

View File

@ -1,12 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
//$Id$
package org.hibernate.orm.test.annotations.polymorphism;
public class Automobile {
}

View File

@ -1,63 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
//$Id$
package org.hibernate.orm.test.annotations.polymorphism;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import org.hibernate.annotations.Polymorphism;
import org.hibernate.annotations.PolymorphismType;
/**
* @author Emmanuel Bernard
*/
@Entity
@Inheritance(strategy= InheritanceType.TABLE_PER_CLASS)
@Polymorphism(type = PolymorphismType.EXPLICIT)
public class Car extends Automobile {
@Id
@GeneratedValue
private long id;
private String model;
@ManyToOne
// purposefully refer to a non-PK column (HHH-7915)
@JoinColumn( referencedColumnName = "REGION_CODE")
private MarketRegion marketRegion;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public MarketRegion getMarketRegion() {
return marketRegion;
}
public void setMarketRegion(MarketRegion marketRegion) {
this.marketRegion = marketRegion;
}
}

View File

@ -1,42 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.annotations.polymorphism;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
/**
* @author Brett Meyer
*/
@Entity
public class MarketRegion {
@Id
@GeneratedValue
private long id;
@Column(name = "REGION_CODE")
private String regionCode;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getRegionCode() {
return regionCode;
}
public void setRegionCode(String regionCode) {
this.regionCode = regionCode;
}
}

View File

@ -1,86 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.annotations.polymorphism;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;
/**
* @author Emmanuel Bernard
* @author Brett Meyer
*/
public class PolymorphismTest extends BaseCoreFunctionalTestCase {
@Test
public void testPolymorphism() throws Exception {
Car car = new Car();
car.setModel( "SUV" );
SportCar car2 = new SportCar();
car2.setModel( "350Z" );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( car );
s.persist( car2 );
s.flush();
assertEquals( 2, s.createQuery( "select car from Car car").list().size() );
// Support for querying a type which has no entity subtypes was removed and now throws an error
// assertEquals( 0, s.createQuery( "select count(m) from " + Automobile.class.getName() + " m").list().size() );
tx.rollback();
s.close();
}
@Test
@TestForIssue(jiraKey = "HHH-7915")
public void testNonPkInheritedFk() throws Exception {
MarketRegion region1 = new MarketRegion();
region1.setRegionCode( "US" );
MarketRegion region2 = new MarketRegion();
region2.setRegionCode( "EU" );
Car car = new Car();
car.setModel( "SUV" );
car.setMarketRegion( region1 );
SportCar car2 = new SportCar();
car2.setModel( "350Z" );
car2.setMarketRegion( region2 );
Session s = openSession();
Transaction tx = s.beginTransaction();
s.persist( region1 );
s.persist( region2 );
s.persist( car );
s.persist( car2 );
s.flush();
assertEquals( 1, s.createQuery( "select car from Car car where car.marketRegion.regionCode='US'")
.list().size() );
assertEquals( 1, s.createQuery( "select car from SportCar car where car.marketRegion.regionCode='EU'")
.list().size() );
tx.rollback();
s.close();
}
@Override
protected Class[] getAnnotatedClasses() {
return new Class[] {
Car.class,
SportCar.class,
MarketRegion.class
};
}
}

View File

@ -1,23 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
//$Id$
package org.hibernate.orm.test.annotations.polymorphism;
import jakarta.persistence.Entity;
import jakarta.persistence.Table;
import org.hibernate.annotations.Polymorphism;
import org.hibernate.annotations.PolymorphismType;
/**
* @author Emmanuel Bernard
*/
@Entity
@Table(name = "sport_car")
@Polymorphism(type = PolymorphismType.EXPLICIT) //raise a warn
public class SportCar extends Car {
}

View File

@ -1,19 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.inheritance.polymorphism;
/**
* @author Vlad Mihalcea
*/
//tag::entity-inheritance-polymorphism-interface-example[]
public interface DomainModelEntity<ID> {
ID getId();
Integer getVersion();
}
//end::entity-inheritance-polymorphism-interface-example[]

View File

@ -1,157 +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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.orm.test.inheritance.polymorphism;
import java.util.List;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Version;
import org.hibernate.annotations.Polymorphism;
import org.hibernate.annotations.PolymorphismType;
import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase;
import org.junit.Test;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
/**
* @author Vlad Mihalcea
*/
public class ExplicitPolymorphismTest extends BaseEntityManagerFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Book.class,
Blog.class,
};
}
@Test
public void test() {
doInJPA(this::entityManagerFactory, entityManager -> {
//tag::entity-inheritance-polymorphism-persist-example[]
Book book = new Book();
book.setId(1L);
book.setAuthor("Vlad Mihalcea");
book.setTitle("High-Performance Java Persistence");
entityManager.persist(book);
Blog blog = new Blog();
blog.setId(1L);
blog.setSite("vladmihalcea.com");
entityManager.persist(blog);
//end::entity-inheritance-polymorphism-persist-example[]
});
doInJPA(this::entityManagerFactory, entityManager -> {
//tag::entity-inheritance-polymorphism-fetch-example[]
List<DomainModelEntity> accounts = entityManager
.createQuery(
"select e " +
"from org.hibernate.orm.test.inheritance.polymorphism.DomainModelEntity e")
.getResultList();
assertEquals(1, accounts.size());
assertTrue(accounts.get(0) instanceof Book);
//end::entity-inheritance-polymorphism-fetch-example[]
});
}
//tag::entity-inheritance-polymorphism-mapping-example[]
@Entity(name = "Event")
public static class Book implements DomainModelEntity<Long> {
@Id
private Long id;
@Version
private Integer version;
private String title;
private String author;
//Getter and setters omitted for brevity
//end::entity-inheritance-polymorphism-mapping-example[]
@Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public Integer getVersion() {
return version;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
//tag::entity-inheritance-polymorphism-mapping-example[]
}
@Entity(name = "Blog")
@Polymorphism(type = PolymorphismType.EXPLICIT)
public static class Blog implements DomainModelEntity<Long> {
@Id
private Long id;
@Version
private Integer version;
private String site;
//Getter and setters omitted for brevity
//end::entity-inheritance-polymorphism-mapping-example[]
@Override
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Override
public Integer getVersion() {
return version;
}
public String getSite() {
return site;
}
public void setSite(String site) {
this.site = site;
}
//tag::entity-inheritance-polymorphism-mapping-example[]
}
//end::entity-inheritance-polymorphism-mapping-example[]
}