Add support for non-synthetic virtual model parts
This commit is contained in:
parent
fb882f56f3
commit
4e5a28deaa
|
@ -1870,24 +1870,16 @@ public class ModelBinder {
|
||||||
|
|
||||||
componentBinding.createForeignKey();
|
componentBinding.createForeignKey();
|
||||||
|
|
||||||
final Property attribute;
|
final Property attribute = new Property();
|
||||||
if ( embeddedSource.isVirtualAttribute() ) {
|
|
||||||
attribute = new SyntheticProperty() {
|
|
||||||
@Override
|
|
||||||
public String getPropertyAccessorName() {
|
|
||||||
return "embedded";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
attribute = new Property();
|
|
||||||
}
|
|
||||||
attribute.setValue( componentBinding );
|
attribute.setValue( componentBinding );
|
||||||
bindProperty(
|
bindProperty(
|
||||||
sourceDocument,
|
sourceDocument,
|
||||||
embeddedSource,
|
embeddedSource,
|
||||||
attribute
|
attribute
|
||||||
);
|
);
|
||||||
|
if ( embeddedSource.isVirtualAttribute() ) {
|
||||||
|
attribute.setPropertyAccessorName( "embedded" );
|
||||||
|
}
|
||||||
|
|
||||||
return attribute;
|
return attribute;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ import org.hibernate.metamodel.model.domain.internal.MappedSuperclassTypeImpl;
|
||||||
import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl;
|
import org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl;
|
||||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||||
import org.hibernate.type.descriptor.java.JavaType;
|
import org.hibernate.type.descriptor.java.JavaType;
|
||||||
|
import org.hibernate.type.descriptor.java.spi.EntityJavaTypeDescriptor;
|
||||||
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
|
import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry;
|
||||||
import org.hibernate.type.spi.TypeConfiguration;
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
@ -78,6 +79,7 @@ public class MetadataContext {
|
||||||
private final Set<MappedSuperclass> knownMappedSuperclasses;
|
private final Set<MappedSuperclass> knownMappedSuperclasses;
|
||||||
private final TypeConfiguration typeConfiguration;
|
private final TypeConfiguration typeConfiguration;
|
||||||
private final JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting;
|
private final JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting;
|
||||||
|
private final JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting;
|
||||||
private final AttributeFactory attributeFactory = new AttributeFactory( this );
|
private final AttributeFactory attributeFactory = new AttributeFactory( this );
|
||||||
|
|
||||||
private final Map<Class<?>, EntityDomainType<?>> entityTypes = new HashMap<>();
|
private final Map<Class<?>, EntityDomainType<?>> entityTypes = new HashMap<>();
|
||||||
|
@ -105,12 +107,14 @@ public class MetadataContext {
|
||||||
MappingMetamodel mappingMetamodel,
|
MappingMetamodel mappingMetamodel,
|
||||||
MetadataImplementor bootMetamodel,
|
MetadataImplementor bootMetamodel,
|
||||||
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting,
|
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting,
|
||||||
|
JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting,
|
||||||
RuntimeModelCreationContext runtimeModelCreationContext) {
|
RuntimeModelCreationContext runtimeModelCreationContext) {
|
||||||
this.jpaMetamodel = jpaMetamodel;
|
this.jpaMetamodel = jpaMetamodel;
|
||||||
this.metamodel = mappingMetamodel;
|
this.metamodel = mappingMetamodel;
|
||||||
this.knownMappedSuperclasses = bootMetamodel.getMappedSuperclassMappingsCopy();
|
this.knownMappedSuperclasses = bootMetamodel.getMappedSuperclassMappingsCopy();
|
||||||
this.typeConfiguration = runtimeModelCreationContext.getTypeConfiguration();
|
this.typeConfiguration = runtimeModelCreationContext.getTypeConfiguration();
|
||||||
this.jpaStaticMetaModelPopulationSetting = jpaStaticMetaModelPopulationSetting;
|
this.jpaStaticMetaModelPopulationSetting = jpaStaticMetaModelPopulationSetting;
|
||||||
|
this.jpaMetaModelPopulationSetting = jpaMetaModelPopulationSetting;
|
||||||
this.runtimeModelCreationContext = runtimeModelCreationContext;
|
this.runtimeModelCreationContext = runtimeModelCreationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,13 +291,12 @@ public class MetadataContext {
|
||||||
property
|
property
|
||||||
);
|
);
|
||||||
if ( attribute != null ) {
|
if ( attribute != null ) {
|
||||||
( (AttributeContainer<Object>) jpaMapping ).getInFlightAccess().addAttribute( attribute );
|
addAttribute( jpaMapping, attribute );
|
||||||
if ( property.isNaturalIdentifier() ) {
|
if ( property.isNaturalIdentifier() ) {
|
||||||
( ( AttributeContainer<Object>) jpaMapping ).getInFlightAccess()
|
( ( AttributeContainer<Object>) jpaMapping ).getInFlightAccess()
|
||||||
.applyNaturalIdAttribute( attribute );
|
.applyNaturalIdAttribute( attribute );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
( (AttributeContainer<?>) jpaMapping ).getInFlightAccess().finishUp();
|
( (AttributeContainer<?>) jpaMapping ).getInFlightAccess().finishUp();
|
||||||
|
@ -329,7 +332,7 @@ public class MetadataContext {
|
||||||
}
|
}
|
||||||
final PersistentAttribute<Object, ?> attribute = attributeFactory.buildAttribute( jpaType, property );
|
final PersistentAttribute<Object, ?> attribute = attributeFactory.buildAttribute( jpaType, property );
|
||||||
if ( attribute != null ) {
|
if ( attribute != null ) {
|
||||||
( (AttributeContainer<Object>) jpaType ).getInFlightAccess().addAttribute( attribute );
|
addAttribute( jpaType, attribute );
|
||||||
if ( property.isNaturalIdentifier() ) {
|
if ( property.isNaturalIdentifier() ) {
|
||||||
( ( AttributeContainer<Object>) jpaType ).getInFlightAccess()
|
( ( AttributeContainer<Object>) jpaType ).getInFlightAccess()
|
||||||
.applyNaturalIdAttribute( attribute );
|
.applyNaturalIdAttribute( attribute );
|
||||||
|
@ -370,7 +373,7 @@ public class MetadataContext {
|
||||||
final Property property = propertyItr.next();
|
final Property property = propertyItr.next();
|
||||||
final PersistentAttribute<Object, ?> attribute = attributeFactory.buildAttribute( (ManagedDomainType<Object>) embeddable, property );
|
final PersistentAttribute<Object, ?> attribute = attributeFactory.buildAttribute( (ManagedDomainType<Object>) embeddable, property );
|
||||||
if ( attribute != null ) {
|
if ( attribute != null ) {
|
||||||
( ( AttributeContainer<Object>) embeddable ).getInFlightAccess().addAttribute( attribute );
|
addAttribute( embeddable, attribute );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,6 +387,27 @@ public class MetadataContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addAttribute(ManagedDomainType<?> type, PersistentAttribute<Object, ?> attribute) {
|
||||||
|
final AttributeContainer.InFlightAccess<Object> inFlightAccess = ( (AttributeContainer<Object>) type ).getInFlightAccess();
|
||||||
|
final boolean virtual = attribute.getPersistentAttributeType() == Attribute.PersistentAttributeType.EMBEDDED
|
||||||
|
&& attribute.getAttributeJavaTypeDescriptor() instanceof EntityJavaTypeDescriptor<?>;
|
||||||
|
if ( virtual ) {
|
||||||
|
final EmbeddableDomainType<?> embeddableDomainType = (EmbeddableDomainType<?>) attribute.getValueGraphType();
|
||||||
|
final Component component = componentByEmbeddable.get( embeddableDomainType );
|
||||||
|
final Iterator<Property> propertyItr = component.getPropertyIterator();
|
||||||
|
while ( propertyItr.hasNext() ) {
|
||||||
|
final Property property = propertyItr.next();
|
||||||
|
final PersistentAttribute<Object, ?> subAttribute = attributeFactory.buildAttribute( (ManagedDomainType<Object>) embeddableDomainType, property );
|
||||||
|
if ( subAttribute != null ) {
|
||||||
|
inFlightAccess.addAttribute( subAttribute );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( jpaMetaModelPopulationSetting != JpaMetaModelPopulationSetting.ENABLED ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inFlightAccess.addAttribute( attribute );
|
||||||
|
}
|
||||||
|
|
||||||
// 1) create the part
|
// 1) create the part
|
||||||
// 2) register the part (mapping role)
|
// 2) register the part (mapping role)
|
||||||
|
|
|
@ -474,6 +474,7 @@ public class JpaMetamodelImpl implements JpaMetamodel, Serializable {
|
||||||
mappingMetamodel,
|
mappingMetamodel,
|
||||||
bootMetamodel,
|
bootMetamodel,
|
||||||
jpaStaticMetaModelPopulationSetting,
|
jpaStaticMetaModelPopulationSetting,
|
||||||
|
jpaMetaModelPopulationSetting,
|
||||||
runtimeModelCreationContext
|
runtimeModelCreationContext
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,7 @@ import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.AttributeMetadata;
|
import org.hibernate.metamodel.mapping.AttributeMetadata;
|
||||||
import org.hibernate.metamodel.mapping.AttributeMetadataAccess;
|
import org.hibernate.metamodel.mapping.AttributeMetadataAccess;
|
||||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||||
|
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||||
|
@ -175,6 +176,7 @@ import org.hibernate.metamodel.mapping.SelectableConsumer;
|
||||||
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
|
||||||
import org.hibernate.metamodel.mapping.StateArrayContributorMapping;
|
import org.hibernate.metamodel.mapping.StateArrayContributorMapping;
|
||||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
|
||||||
|
import org.hibernate.metamodel.mapping.VirtualModelPart;
|
||||||
import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl;
|
import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl;
|
||||||
import org.hibernate.metamodel.mapping.internal.CompoundNaturalIdMapping;
|
import org.hibernate.metamodel.mapping.internal.CompoundNaturalIdMapping;
|
||||||
import org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping;
|
import org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping;
|
||||||
|
@ -6362,7 +6364,21 @@ public abstract class AbstractEntityPersister
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return getIdentifierModelPart( name, treatTargetType );
|
final ModelPart identifierModelPart = getIdentifierModelPart( name, treatTargetType );
|
||||||
|
if ( identifierModelPart != null ) {
|
||||||
|
return identifierModelPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( AttributeMapping attribute : declaredAttributeMappings.values() ) {
|
||||||
|
if ( attribute instanceof EmbeddableValuedModelPart && attribute instanceof VirtualModelPart ) {
|
||||||
|
final ModelPart subPart = ( (EmbeddableValuedModelPart) attribute ).findSubPart( name, null );
|
||||||
|
if ( subPart != null ) {
|
||||||
|
return subPart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//$Id: Detail.java 4602 2004-09-26 11:42:47Z oneovthafew $
|
//$Id: Detail.java 4602 2004-09-26 11:42:47Z oneovthafew $
|
||||||
package org.hibernate.test.formulajoin;
|
package org.hibernate.orm.test.formulajoin;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -4,13 +4,14 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.formulajoin;
|
package org.hibernate.orm.test.formulajoin;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.dialect.PostgreSQL81Dialect;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.dialect.PostgreSQLDialect;
|
import org.hibernate.dialect.PostgreSQLDialect;
|
||||||
|
|
||||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
@ -23,10 +24,18 @@ import static org.junit.Assert.assertTrue;
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
*/
|
*/
|
||||||
public class FormulaJoinTest extends BaseCoreFunctionalTestCase {
|
public class FormulaJoinTest extends BaseCoreFunctionalTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
public String[] getMappings() {
|
public String[] getMappings() {
|
||||||
return new String[] { "formulajoin/Root.hbm.xml" };
|
return new String[] { "formulajoin/Root.hbm.xml" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(Configuration configuration) {
|
||||||
|
super.configure( configuration );
|
||||||
|
configuration.setProperty( AvailableSettings.JPA_METAMODEL_POPULATION, "enabled" );
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFormulaJoin() {
|
public void testFormulaJoin() {
|
||||||
Session s = openSession();
|
Session s = openSession();
|
||||||
|
@ -50,7 +59,7 @@ public class FormulaJoinTest extends BaseCoreFunctionalTestCase {
|
||||||
tx.commit();
|
tx.commit();
|
||||||
s.close();
|
s.close();
|
||||||
|
|
||||||
if ( getDialect() instanceof PostgreSQLDialect || getDialect() instanceof PostgreSQL81Dialect ) return;
|
if ( getDialect() instanceof PostgreSQLDialect ) return;
|
||||||
|
|
||||||
s = openSession();
|
s = openSession();
|
||||||
tx = s.beginTransaction();
|
tx = s.beginTransaction();
|
||||||
|
@ -83,11 +92,23 @@ public class FormulaJoinTest extends BaseCoreFunctionalTestCase {
|
||||||
tx.commit();
|
tx.commit();
|
||||||
s.close();
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
tx = s.beginTransaction();
|
||||||
|
l = s.createQuery("from Detail d join fetch d.root").list();
|
||||||
|
assertEquals( l.size(), 2 );
|
||||||
|
tx.commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
s = openSession();
|
s = openSession();
|
||||||
tx = s.beginTransaction();
|
tx = s.beginTransaction();
|
||||||
l = s.createQuery("from Detail d join fetch d.currentRoot.root m join fetch m.detail").list();
|
l = s.createQuery("from Detail d join fetch d.currentRoot.root m join fetch m.detail").list();
|
||||||
assertEquals( l.size(), 2 );
|
assertEquals( l.size(), 2 );
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
tx = s.beginTransaction();
|
||||||
|
l = s.createQuery("from Detail d join fetch d.root m join fetch m.detail").list();
|
||||||
|
assertEquals( l.size(), 2 );
|
||||||
|
|
||||||
s.createQuery("delete from Detail").executeUpdate();
|
s.createQuery("delete from Detail").executeUpdate();
|
||||||
s.createQuery("delete from Root").executeUpdate();
|
s.createQuery("delete from Root").executeUpdate();
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<hibernate-mapping package="org.hibernate.test.formulajoin">
|
<hibernate-mapping package="org.hibernate.orm.test.formulajoin">
|
||||||
|
|
||||||
<class name="Root" table="t_roots">
|
<class name="Root" table="t_roots">
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
* 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>.
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.formulajoin;
|
package org.hibernate.orm.test.formulajoin;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
Loading…
Reference in New Issue