HHH-16783 allow implicit discriminator mappings in @Any
This commit is contained in:
parent
b364a9d50a
commit
925d09528d
|
@ -11,12 +11,15 @@ import java.util.Map;
|
|||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
import org.hibernate.metamodel.RepresentationMode;
|
||||
import org.hibernate.metamodel.mapping.internal.DiscriminatorValueDetailsImpl;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
|
@ -61,7 +64,8 @@ public class DiscriminatorConverter<O,R> implements BasicValueConverter<O,R> {
|
|||
role,
|
||||
domainJavaType,
|
||||
underlyingJdbcMapping.getJavaTypeDescriptor(),
|
||||
valueDetailsList
|
||||
valueDetailsList,
|
||||
mappingMetamodel
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -71,15 +75,18 @@ public class DiscriminatorConverter<O,R> implements BasicValueConverter<O,R> {
|
|||
|
||||
private final Map<Object, DiscriminatorValueDetails> discriminatorValueToEntityNameMap;
|
||||
private final Map<String,DiscriminatorValueDetails> entityNameToDiscriminatorValueMap;
|
||||
private final MappingMetamodelImplementor mappingMetamodel;
|
||||
|
||||
public DiscriminatorConverter(
|
||||
NavigableRole discriminatorRole,
|
||||
JavaType<O> domainJavaType,
|
||||
JavaType<R> relationalJavaType,
|
||||
List<DiscriminatorValueDetails> valueMappings) {
|
||||
List<DiscriminatorValueDetails> valueMappings,
|
||||
MappingMetamodelImplementor mappingMetamodel) {
|
||||
this.discriminatorRole = discriminatorRole;
|
||||
this.domainJavaType = domainJavaType;
|
||||
this.relationalJavaType = relationalJavaType;
|
||||
this.mappingMetamodel = mappingMetamodel;
|
||||
|
||||
this.discriminatorValueToEntityNameMap = CollectionHelper.concurrentMap( valueMappings.size() );
|
||||
this.entityNameToDiscriminatorValueMap = CollectionHelper.concurrentMap( valueMappings.size() );
|
||||
|
@ -125,7 +132,17 @@ public class DiscriminatorConverter<O,R> implements BasicValueConverter<O,R> {
|
|||
}
|
||||
|
||||
public DiscriminatorValueDetails getDetailsForEntityName(String entityName) {
|
||||
return entityNameToDiscriminatorValueMap.get( entityName );
|
||||
DiscriminatorValueDetails valueDetails = entityNameToDiscriminatorValueMap.get( entityName );
|
||||
if ( valueDetails!= null) {
|
||||
return valueDetails;
|
||||
}
|
||||
|
||||
EntityPersister persister = mappingMetamodel.findEntityDescriptor( entityName );
|
||||
if ( persister!= null ) {
|
||||
return new DiscriminatorValueDetailsImpl( entityName, persister );
|
||||
}
|
||||
|
||||
throw new AssertionFailure( "Unrecognized entity name: " + entityName );
|
||||
}
|
||||
|
||||
public DiscriminatorValueDetails getDetailsForDiscriminatorValue(Object value) {
|
||||
|
@ -138,7 +155,20 @@ public class DiscriminatorConverter<O,R> implements BasicValueConverter<O,R> {
|
|||
return valueMatch;
|
||||
}
|
||||
|
||||
return discriminatorValueToEntityNameMap.get( NOT_NULL_DISCRIMINATOR );
|
||||
final DiscriminatorValueDetails notNullMatch = discriminatorValueToEntityNameMap.get( NOT_NULL_DISCRIMINATOR );
|
||||
if ( notNullMatch != null ) {
|
||||
return notNullMatch;
|
||||
}
|
||||
|
||||
if ( value instanceof String ) {
|
||||
String entityName = mappingMetamodel.getImportedName( (String) value );
|
||||
EntityPersister persister = mappingMetamodel.findEntityDescriptor( entityName );
|
||||
if ( persister!= null ) {
|
||||
return new DiscriminatorValueDetailsImpl( entityName, persister );
|
||||
}
|
||||
}
|
||||
|
||||
throw new HibernateException( "Unrecognized discriminator value: " + value );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -41,7 +41,7 @@ import org.hibernate.type.descriptor.java.JavaType;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class AnyKeyPart implements BasicValuedModelPart, FetchOptions {
|
||||
public static final String ROLE_NAME = "{key}";
|
||||
public static final String KEY_NAME = "{key}";
|
||||
|
||||
private final NavigableRole navigableRole;
|
||||
private final String table;
|
||||
|
@ -163,7 +163,7 @@ public class AnyKeyPart implements BasicValuedModelPart, FetchOptions {
|
|||
|
||||
@Override
|
||||
public String getPartName() {
|
||||
return ROLE_NAME;
|
||||
return KEY_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -101,7 +101,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
|
|||
|
||||
final BasicType<?> keyType = (BasicType<?>) anyType.getIdentifierType();
|
||||
final BasicValuedModelPart keyPart = new AnyKeyPart(
|
||||
containerRole.append( AnyKeyPart.ROLE_NAME),
|
||||
containerRole.append( AnyKeyPart.KEY_NAME ),
|
||||
declaringModelPart,
|
||||
tableName,
|
||||
keyColumn.getText( dialect ),
|
||||
|
@ -245,7 +245,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
|
|||
return getDiscriminatorPart();
|
||||
}
|
||||
|
||||
if ( AnyKeyPart.ROLE_NAME.equals( name ) ) {
|
||||
if ( AnyKeyPart.KEY_NAME.equals( name ) ) {
|
||||
return getKeyPart();
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
|
|||
}
|
||||
|
||||
if ( identifierMapping instanceof SingleAttributeIdentifierMapping ) {
|
||||
final String idAttrName = ( (SingleAttributeIdentifierMapping) identifierMapping ).getAttributeName();
|
||||
final String idAttrName = identifierMapping.getAttributeName();
|
||||
if ( idAttrName.equals( name ) ) {
|
||||
return getKeyPart();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
package org.hibernate.metamodel.model.domain.internal;
|
||||
|
||||
import org.hibernate.metamodel.UnsupportedMappingException;
|
||||
import org.hibernate.metamodel.mapping.internal.AnyDiscriminatorPart;
|
||||
import org.hibernate.metamodel.mapping.internal.AnyKeyPart;
|
||||
import org.hibernate.metamodel.model.domain.AnyMappingDomainType;
|
||||
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
||||
import org.hibernate.spi.NavigablePath;
|
||||
|
@ -30,7 +32,7 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
|
|||
BindableType jpaBindableType) {
|
||||
super( localPathName, pathModel, domainType, jpaBindableType );
|
||||
keyPathSource = new BasicSqmPathSource<>(
|
||||
"id",
|
||||
AnyKeyPart.KEY_NAME,
|
||||
null,
|
||||
(BasicDomainType<?>) domainType.getKeyType(),
|
||||
domainType.getKeyType().getExpressibleJavaType(),
|
||||
|
@ -52,14 +54,16 @@ public class AnyMappingSqmPathSource<J> extends AbstractSqmPathSource<J> {
|
|||
|
||||
@Override
|
||||
public SqmPathSource<?> findSubPathSource(String name) {
|
||||
if ( "id".equals( name ) ) {
|
||||
switch (name) {
|
||||
case "id": // deprecated HQL .id syntax
|
||||
case AnyKeyPart.KEY_NAME: // standard id() function
|
||||
return keyPathSource;
|
||||
}
|
||||
else if("{discriminator}".equals( name )) {
|
||||
case "class": // deprecated HQL .class syntax
|
||||
case AnyDiscriminatorPart.ROLE_NAME: // standard type() function
|
||||
return discriminatorPathSource;
|
||||
default:
|
||||
throw new UnsupportedMappingException( "Only the key and discriminator parts of an '@Any' mapping may be dereferenced" );
|
||||
}
|
||||
|
||||
throw new UnsupportedMappingException( "De-referencing parts of an ANY mapping, other than the key, is not supported" );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -44,6 +44,7 @@ import org.hibernate.internal.util.collections.Stack;
|
|||
import org.hibernate.internal.util.collections.StandardStack;
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.metamodel.mapping.CollectionPart;
|
||||
import org.hibernate.metamodel.mapping.internal.AnyKeyPart;
|
||||
import org.hibernate.metamodel.model.domain.BasicDomainType;
|
||||
import org.hibernate.metamodel.model.domain.DomainType;
|
||||
import org.hibernate.metamodel.model.domain.EntityDomainType;
|
||||
|
@ -2793,7 +2794,7 @@ public class SemanticQueryBuilder<R> extends HqlParserBaseVisitor<Object> implem
|
|||
return sqmPath.get( identifierDescriptor.getPathName() );
|
||||
}
|
||||
else if ( sqmPath instanceof SqmAnyValuedSimplePath<?> ) {
|
||||
return sqmPath.resolvePathPart("id", true, getCurrentProcessingState().getCreationState() );
|
||||
return sqmPath.resolvePathPart( AnyKeyPart.KEY_NAME, true, getCurrentProcessingState().getCreationState() );
|
||||
}
|
||||
else {
|
||||
throw new SemanticException( "Path does not resolve to an entity type '" + sqmPath.getNavigablePath() + "'" );
|
||||
|
|
|
@ -121,7 +121,7 @@ public class BasicValuedPathInterpretation<T> extends AbstractSqmPathInterpretat
|
|||
}
|
||||
}
|
||||
|
||||
throw new SemanticException( "`" + sqmPath.getNavigablePath() + "` did not reference a known model part" );
|
||||
throw new SemanticException( "'" + sqmPath.getNavigablePath() + "' did not reference a known model part" );
|
||||
}
|
||||
|
||||
final TableReference tableReference = tableGroup.resolveTableReference(
|
||||
|
|
|
@ -0,0 +1,357 @@
|
|||
/*
|
||||
* 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.any.annotations;
|
||||
|
||||
import org.hibernate.query.spi.QueryImplementor;
|
||||
import org.hibernate.testing.TestForIssue;
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
@DomainModel(
|
||||
annotatedPackageNames = "org.hibernate.orm.test.any.annotations",
|
||||
annotatedClasses = {
|
||||
StringProperty.class,
|
||||
IntegerProperty.class,
|
||||
LongProperty.class,
|
||||
ImplicitPropertySet.class,
|
||||
ImplicitPropertyMap.class,
|
||||
ImplicitPropertyList.class,
|
||||
ImplicitPropertyHolder.class,
|
||||
CharProperty.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
public class AnyImplicitDiscriminatorTest {
|
||||
@BeforeEach
|
||||
public void createTestData(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
{
|
||||
final ImplicitPropertySet set1 = new ImplicitPropertySet( "string" );
|
||||
final Property property = new StringProperty( "name", "Alex" );
|
||||
set1.setSomeProperty( property );
|
||||
set1.addGeneralProperty( property );
|
||||
session.persist( set1 );
|
||||
|
||||
final ImplicitPropertySet set2 = new ImplicitPropertySet( "integer" );
|
||||
final Property property2 = new IntegerProperty( "age", 33 );
|
||||
set2.setSomeProperty( property2 );
|
||||
set2.addGeneralProperty( property2 );
|
||||
session.persist( set2 );
|
||||
}
|
||||
|
||||
{
|
||||
final ImplicitPropertyMap map = new ImplicitPropertyMap( "sample" );
|
||||
map.getProperties().put( "name", new StringProperty( "name", "Alex" ) );
|
||||
map.getProperties().put( "age", new IntegerProperty( "age", 33 ) );
|
||||
session.persist( map );
|
||||
}
|
||||
|
||||
{
|
||||
StringProperty nameProperty = new StringProperty( "name", "John Doe" );
|
||||
session.persist( nameProperty );
|
||||
|
||||
ImplicitPropertyHolder namePropertyHolder = new ImplicitPropertyHolder();
|
||||
namePropertyHolder.setId( 1 );
|
||||
namePropertyHolder.setProperty( nameProperty );
|
||||
|
||||
session.persist( namePropertyHolder );
|
||||
|
||||
final IntegerProperty ageProperty = new IntegerProperty( "age", 23 );
|
||||
session.persist( ageProperty );
|
||||
|
||||
ImplicitPropertyHolder agePropertyHolder = new ImplicitPropertyHolder();
|
||||
agePropertyHolder.setId( 2 );
|
||||
agePropertyHolder.setProperty( ageProperty );
|
||||
|
||||
session.persist( agePropertyHolder );
|
||||
}
|
||||
|
||||
{
|
||||
final ImplicitPropertyList list = new ImplicitPropertyList( "sample" );
|
||||
final StringProperty stringProperty = new StringProperty( "name", "Alex" );
|
||||
final IntegerProperty integerProperty = new IntegerProperty( "age", 33 );
|
||||
final LongProperty longProperty = new LongProperty( "distance", 121L );
|
||||
final CharProperty charProp = new CharProperty( "Est", 'E' );
|
||||
|
||||
list.setSomeProperty( longProperty );
|
||||
|
||||
list.addGeneralProperty( stringProperty );
|
||||
list.addGeneralProperty( integerProperty );
|
||||
list.addGeneralProperty( longProperty );
|
||||
list.addGeneralProperty( charProp );
|
||||
|
||||
session.persist( list );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void dropTestData(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createMutationQuery( "delete StringProperty" ).executeUpdate();
|
||||
session.createMutationQuery( "delete IntegerProperty" ).executeUpdate();
|
||||
session.createMutationQuery( "delete LongProperty" ).executeUpdate();
|
||||
session.createMutationQuery( "delete CharProperty" ).executeUpdate();
|
||||
|
||||
session.createMutationQuery( "delete ImplicitPropertyHolder" ).executeUpdate();
|
||||
session.createMutationQuery( "delete ImplicitPropertyList" ).executeUpdate();
|
||||
session.createMutationQuery( "delete ImplicitPropertyMap" ).executeUpdate();
|
||||
session.createMutationQuery( "delete ImplicitPropertySet" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-16732")
|
||||
public void testHqlAnyIdQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
List<PropertySet> list1 = session.createQuery(
|
||||
"select p from ImplicitPropertyHolder p where id(p.property) = 666",
|
||||
PropertySet.class ).list();
|
||||
assertEquals( 0, list1.size() );
|
||||
List<PropertySet> list2 = session.createQuery(
|
||||
"select p from ImplicitPropertyHolder p where type(p.property) = IntegerProperty",
|
||||
PropertySet.class ).list();
|
||||
assertEquals( 1, list2.size() );
|
||||
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-15323")
|
||||
public void testHqlCollectionTypeQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
List<ImplicitPropertySet> propertySets = session.createQuery(
|
||||
"select p from ImplicitPropertySet p where type(p.generalProperties) = IntegerProperty ",
|
||||
ImplicitPropertySet.class ).list();
|
||||
assertEquals( 1, propertySets.size() );
|
||||
|
||||
ImplicitPropertySet propertySet = propertySets.get( 0 );
|
||||
assertEquals( 1, propertySet.getGeneralProperties().size() );
|
||||
|
||||
assertEquals( "age", propertySet.getGeneralProperties().get( 0 ).getName() );
|
||||
|
||||
propertySets = session.createQuery(
|
||||
"select p from ImplicitPropertySet p where type(p.generalProperties) = StringProperty ",
|
||||
ImplicitPropertySet.class ).list();
|
||||
assertEquals( 1, propertySets.size() );
|
||||
|
||||
propertySet = propertySets.get( 0 );
|
||||
assertEquals( 1, propertySet.getGeneralProperties().size() );
|
||||
|
||||
assertEquals( "name", propertySet.getGeneralProperties().get( 0 ).getName() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-15442")
|
||||
public void testHqlCollectionTypeQueryWithParameters(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
List<ImplicitPropertySet> propertySets = session.createQuery(
|
||||
"select p from ImplicitPropertySet p where type(p.generalProperties) = :prop ",
|
||||
ImplicitPropertySet.class )
|
||||
.setParameter( "prop", IntegerProperty.class)
|
||||
.list();
|
||||
assertEquals( 1, propertySets.size() );
|
||||
|
||||
ImplicitPropertySet propertySet = propertySets.get( 0 );
|
||||
assertEquals( 1, propertySet.getGeneralProperties().size() );
|
||||
|
||||
assertEquals( "age", propertySet.getGeneralProperties().get( 0 ).getName() );
|
||||
|
||||
propertySets = session.createQuery(
|
||||
"select p from ImplicitPropertySet p where type(p.generalProperties) = :prop ",
|
||||
ImplicitPropertySet.class )
|
||||
.setParameter( "prop", StringProperty.class)
|
||||
.list();
|
||||
assertEquals( 1, propertySets.size() );
|
||||
|
||||
propertySet = propertySets.get( 0 );
|
||||
assertEquals( 1, propertySet.getGeneralProperties().size() );
|
||||
|
||||
assertEquals( "name", propertySet.getGeneralProperties().get( 0 ).getName() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-15323")
|
||||
public void testHqlTypeQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
List<ImplicitPropertyHolder> propertyHolders = session.createQuery(
|
||||
"select p from ImplicitPropertyHolder p where type(p.property) = IntegerProperty ",
|
||||
ImplicitPropertyHolder.class ).list();
|
||||
assertEquals( 1, propertyHolders.size() );
|
||||
|
||||
assertEquals( "age", propertyHolders.get( 0 ).getProperty().getName() );
|
||||
|
||||
propertyHolders = session.createQuery(
|
||||
"select p from ImplicitPropertyHolder p where type(p.property) = StringProperty ",
|
||||
ImplicitPropertyHolder.class ).list();
|
||||
assertEquals( 1, propertyHolders.size() );
|
||||
|
||||
assertEquals( "name", propertyHolders.get( 0 ).getProperty().getName() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@TestForIssue( jiraKey = "HHH-15442")
|
||||
public void testHqlTypeQueryWithParameter(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
List<ImplicitPropertyHolder> propertyHolders = session.createQuery(
|
||||
"select p from ImplicitPropertyHolder p where type(p.property) = :prop ",
|
||||
ImplicitPropertyHolder.class )
|
||||
.setParameter( "prop", IntegerProperty.class)
|
||||
.list();
|
||||
assertEquals( 1, propertyHolders.size() );
|
||||
|
||||
assertEquals( "age", propertyHolders.get( 0 ).getProperty().getName() );
|
||||
|
||||
propertyHolders = session.createQuery(
|
||||
"select p from ImplicitPropertyHolder p where type(p.property) = :prop ",
|
||||
ImplicitPropertyHolder.class )
|
||||
.setParameter( "prop", StringProperty.class)
|
||||
.list();
|
||||
assertEquals( 1, propertyHolders.size() );
|
||||
|
||||
assertEquals( "name", propertyHolders.get( 0 ).getProperty().getName() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultAnyAssociation(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final QueryImplementor<ImplicitPropertySet> query = session.createQuery(
|
||||
"select s from ImplicitPropertySet s where name = :name",
|
||||
ImplicitPropertySet.class
|
||||
);
|
||||
|
||||
{
|
||||
final ImplicitPropertySet result = query.setParameter( "name", "string" ).uniqueResult();
|
||||
assertNotNull( result );
|
||||
assertNotNull( result.getSomeProperty() );
|
||||
assertTrue( result.getSomeProperty() instanceof StringProperty );
|
||||
assertEquals( "Alex", result.getSomeProperty().asString() );
|
||||
assertNotNull( result.getGeneralProperties() );
|
||||
assertEquals( 1, result.getGeneralProperties().size() );
|
||||
assertEquals( "Alex", result.getGeneralProperties().get( 0 ).asString() );
|
||||
}
|
||||
|
||||
{
|
||||
final ImplicitPropertySet result = query.setParameter( "name", "integer" ).uniqueResult();
|
||||
assertNotNull( result );
|
||||
assertNotNull( result.getSomeProperty() );
|
||||
assertTrue( result.getSomeProperty() instanceof IntegerProperty );
|
||||
assertEquals( "33", result.getSomeProperty().asString() );
|
||||
assertNotNull( result.getGeneralProperties() );
|
||||
assertEquals( 1, result.getGeneralProperties().size() );
|
||||
assertEquals( "33", result.getGeneralProperties().get( 0 ).asString() );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testManyToAnyWithMap(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final ImplicitPropertyMap actualMap = session
|
||||
.createQuery( "SELECT m FROM ImplicitPropertyMap m WHERE m.name = :name", ImplicitPropertyMap.class )
|
||||
.setParameter( "name", "sample" )
|
||||
.uniqueResult();
|
||||
|
||||
assertNotNull( actualMap );
|
||||
assertNotNull( actualMap.getProperties() );
|
||||
|
||||
Property property = actualMap.getProperties().get( "name" );
|
||||
assertNotNull( property );
|
||||
assertTrue( property instanceof StringProperty );
|
||||
assertEquals( "Alex", property.asString() );
|
||||
|
||||
property = actualMap.getProperties().get( "age" );
|
||||
assertNotNull( property );
|
||||
assertTrue( property instanceof IntegerProperty );
|
||||
assertEquals( "33", property.asString() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void
|
||||
testMetaDataUseWithManyToAny(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
//noinspection unchecked
|
||||
final ImplicitPropertyList<Property> actualList = session
|
||||
.createQuery( "SELECT l FROM ImplicitPropertyList l WHERE l.name = :name", ImplicitPropertyList.class )
|
||||
.setParameter( "name", "sample" )
|
||||
.uniqueResult();
|
||||
|
||||
assertNotNull( actualList );
|
||||
assertNotNull( actualList.getGeneralProperties() );
|
||||
assertEquals( 4, actualList.getGeneralProperties().size() );
|
||||
|
||||
Property property = actualList.getSomeProperty();
|
||||
assertNotNull( property );
|
||||
assertTrue( property instanceof LongProperty );
|
||||
assertEquals( "121", property.asString() );
|
||||
|
||||
assertEquals( "Alex", actualList.getGeneralProperties().get( 0 )
|
||||
.asString() );
|
||||
assertEquals( "33", actualList.getGeneralProperties().get( 1 ).asString() );
|
||||
assertEquals( "121", actualList.getGeneralProperties().get( 2 ).asString() );
|
||||
assertEquals( "E", actualList.getGeneralProperties().get( 3 ).asString() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchEager(SessionFactoryScope scope) {
|
||||
final ImplicitPropertySet result = scope.fromTransaction(
|
||||
session -> {
|
||||
final ImplicitPropertySet localResult = session.createQuery(
|
||||
"select s from ImplicitPropertySet s where name = :name",
|
||||
ImplicitPropertySet.class
|
||||
)
|
||||
.setParameter( "name", "string" )
|
||||
.getSingleResult();
|
||||
assertNotNull( localResult );
|
||||
assertNotNull( localResult.getSomeProperty() );
|
||||
|
||||
return localResult;
|
||||
}
|
||||
);
|
||||
|
||||
assertTrue( result.getSomeProperty() instanceof StringProperty );
|
||||
assertEquals( "Alex", result.getSomeProperty().asString() );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.any.annotations;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.Table;
|
||||
import org.hibernate.annotations.Any;
|
||||
import org.hibernate.annotations.AnyKeyJavaClass;
|
||||
|
||||
@Entity
|
||||
@Table(name = "property_holder")
|
||||
public class ImplicitPropertyHolder {
|
||||
|
||||
@Id
|
||||
private Integer id;
|
||||
|
||||
@Any
|
||||
@AnyKeyJavaClass(Integer.class)
|
||||
@Column(name = "property_type")
|
||||
@JoinColumn(name = "property_id")
|
||||
private Property property;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Property getProperty() {
|
||||
return property;
|
||||
}
|
||||
|
||||
public void setProperty(Property property) {
|
||||
this.property = property;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.any.annotations;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.OrderColumn;
|
||||
import jakarta.persistence.Table;
|
||||
import org.hibernate.annotations.Any;
|
||||
import org.hibernate.annotations.AnyDiscriminatorValue;
|
||||
import org.hibernate.annotations.AnyKeyJavaClass;
|
||||
import org.hibernate.annotations.Cascade;
|
||||
import org.hibernate.annotations.CascadeType;
|
||||
import org.hibernate.annotations.ManyToAny;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table( name = "property_list" )
|
||||
public class ImplicitPropertyList<T extends Property> {
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
|
||||
private T someProperty;
|
||||
|
||||
private List<T> generalProperties = new ArrayList<T>();
|
||||
|
||||
public ImplicitPropertyList() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ImplicitPropertyList(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ManyToAny
|
||||
@Column(name = "property_type")
|
||||
@AnyKeyJavaClass( Integer.class )
|
||||
@Cascade( CascadeType.ALL )
|
||||
@JoinTable(name = "list_properties",
|
||||
joinColumns = @JoinColumn(name = "obj_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "property_id")
|
||||
)
|
||||
@OrderColumn(name = "prop_index")
|
||||
public List<T> getGeneralProperties() {
|
||||
return generalProperties;
|
||||
}
|
||||
|
||||
public void setGeneralProperties(List<T> generalProperties) {
|
||||
this.generalProperties = generalProperties;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Any
|
||||
@Column(name = "property_type")
|
||||
@JoinColumn(name = "property_id")
|
||||
@AnyKeyJavaClass( Integer.class )
|
||||
@AnyDiscriminatorValue( discriminator = "C", entity = CharProperty.class )
|
||||
@AnyDiscriminatorValue( discriminator = "I", entity = IntegerProperty.class)
|
||||
@AnyDiscriminatorValue( discriminator = "S", entity = StringProperty.class)
|
||||
@AnyDiscriminatorValue( discriminator = "L", entity = LongProperty.class)
|
||||
@Cascade( CascadeType.ALL )
|
||||
public T getSomeProperty() {
|
||||
return someProperty;
|
||||
}
|
||||
|
||||
public void setSomeProperty(T someProperty) {
|
||||
this.someProperty = someProperty;
|
||||
}
|
||||
|
||||
public void addGeneralProperty(T property) {
|
||||
this.generalProperties.add( property );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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.any.annotations;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.MapKeyColumn;
|
||||
import jakarta.persistence.Table;
|
||||
import org.hibernate.annotations.AnyDiscriminatorValue;
|
||||
import org.hibernate.annotations.AnyKeyJavaClass;
|
||||
import org.hibernate.annotations.Cascade;
|
||||
import org.hibernate.annotations.ManyToAny;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Entity
|
||||
@Table( name = "property_map" )
|
||||
public class ImplicitPropertyMap {
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
private Map<String, Property> properties = new HashMap<String, Property>();
|
||||
|
||||
public ImplicitPropertyMap(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public ImplicitPropertyMap() {
|
||||
super();
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@ManyToAny
|
||||
@Column( name = "property_type" )
|
||||
@AnyKeyJavaClass( Integer.class )
|
||||
@Cascade( org.hibernate.annotations.CascadeType.ALL )
|
||||
@JoinTable(
|
||||
name = "map_properties",
|
||||
joinColumns = @JoinColumn( name = "map_id" ),
|
||||
inverseJoinColumns = @JoinColumn( name = "property_id" ) )
|
||||
@MapKeyColumn( name = "map_key", nullable = false ) //keep for legacy test
|
||||
public Map<String, Property> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(Map<String, Property> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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.any.annotations;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.Table;
|
||||
import org.hibernate.annotations.Any;
|
||||
import org.hibernate.annotations.AnyDiscriminatorValue;
|
||||
import org.hibernate.annotations.AnyKeyJavaClass;
|
||||
import org.hibernate.annotations.Cascade;
|
||||
import org.hibernate.annotations.CascadeType;
|
||||
import org.hibernate.annotations.ManyToAny;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table( name = "property_set" )
|
||||
public class ImplicitPropertySet {
|
||||
private Integer id;
|
||||
private String name;
|
||||
private Property someProperty;
|
||||
|
||||
private List<Property> generalProperties = new ArrayList<Property>();
|
||||
|
||||
public ImplicitPropertySet() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ImplicitPropertySet(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ManyToAny
|
||||
@Column( name = "property_type" )
|
||||
@AnyKeyJavaClass( Integer.class )
|
||||
@Cascade( CascadeType.ALL )
|
||||
@JoinTable(
|
||||
name = "obj_properties",
|
||||
joinColumns = @JoinColumn( name = "obj_id" ),
|
||||
inverseJoinColumns = @JoinColumn( name = "property_id" ) )
|
||||
public List<Property> getGeneralProperties() {
|
||||
return generalProperties;
|
||||
}
|
||||
|
||||
public void setGeneralProperties(List<Property> generalProperties) {
|
||||
this.generalProperties = generalProperties;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Any
|
||||
@Column( name = "property_type" )
|
||||
@AnyKeyJavaClass( Integer.class )
|
||||
@AnyDiscriminatorValue( discriminator = "S", entity = StringProperty.class )
|
||||
@AnyDiscriminatorValue( discriminator = "I", entity = IntegerProperty.class )
|
||||
@Cascade( value = { CascadeType.ALL } )
|
||||
@JoinColumn( name = "property_id" )
|
||||
public Property getSomeProperty() {
|
||||
return someProperty;
|
||||
}
|
||||
|
||||
public void setSomeProperty(Property someProperty) {
|
||||
this.someProperty = someProperty;
|
||||
}
|
||||
|
||||
public void addGeneralProperty(Property property) {
|
||||
this.generalProperties.add( property );
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ package org.hibernate.orm.test.mapping;
|
|||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.MappingMetamodel;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
|
@ -30,6 +31,7 @@ import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
|
||||
/**
|
||||
* Tests access to {@link MappingMetamodel} as API and SPI contracts
|
||||
|
@ -96,7 +98,7 @@ public class MappingModelAccessTests {
|
|||
assertThat( discriminatorMapping.resolveDiscriminatorValue( 0 ).getIndicatedEntity() ).isEqualTo( paymentMapping );
|
||||
assertThat( discriminatorMapping.resolveDiscriminatorValue( 1 ).getIndicatedEntity() ).isEqualTo( cashPaymentMapping );
|
||||
assertThat( discriminatorMapping.resolveDiscriminatorValue( 2 ).getIndicatedEntity() ).isEqualTo( cardPaymentMapping );
|
||||
assertThat( discriminatorMapping.resolveDiscriminatorValue( 3 ) ).isNull();
|
||||
assertThatCode( () -> discriminatorMapping.resolveDiscriminatorValue( 3 ) ).isInstanceOf(HibernateException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -126,6 +128,6 @@ public class MappingModelAccessTests {
|
|||
assertThat( discriminatorMapping.resolveDiscriminatorValue( "Vendor" ).getIndicatedEntity() ).isEqualTo( vendorMapping );
|
||||
assertThat( discriminatorMapping.resolveDiscriminatorValue( "domestic" ).getIndicatedEntity() ).isEqualTo( domesticVendorMapping );
|
||||
assertThat( discriminatorMapping.resolveDiscriminatorValue( "foreign" ).getIndicatedEntity() ).isEqualTo( foreignVendorMapping );
|
||||
assertThat( discriminatorMapping.resolveDiscriminatorValue( "invalid" ) ).isNull();
|
||||
assertThatCode( () -> discriminatorMapping.resolveDiscriminatorValue( "invalid" ) ).isInstanceOf(HibernateException.class);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue