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();
|
||||
|
||||
final Property attribute;
|
||||
if ( embeddedSource.isVirtualAttribute() ) {
|
||||
attribute = new SyntheticProperty() {
|
||||
@Override
|
||||
public String getPropertyAccessorName() {
|
||||
return "embedded";
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
attribute = new Property();
|
||||
}
|
||||
final Property attribute = new Property();
|
||||
attribute.setValue( componentBinding );
|
||||
bindProperty(
|
||||
sourceDocument,
|
||||
embeddedSource,
|
||||
attribute
|
||||
);
|
||||
if ( embeddedSource.isVirtualAttribute() ) {
|
||||
attribute.setPropertyAccessorName( "embedded" );
|
||||
}
|
||||
|
||||
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.spi.RuntimeModelCreationContext;
|
||||
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.spi.TypeConfiguration;
|
||||
|
||||
|
@ -78,6 +79,7 @@ public class MetadataContext {
|
|||
private final Set<MappedSuperclass> knownMappedSuperclasses;
|
||||
private final TypeConfiguration typeConfiguration;
|
||||
private final JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting;
|
||||
private final JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting;
|
||||
private final AttributeFactory attributeFactory = new AttributeFactory( this );
|
||||
|
||||
private final Map<Class<?>, EntityDomainType<?>> entityTypes = new HashMap<>();
|
||||
|
@ -105,12 +107,14 @@ public class MetadataContext {
|
|||
MappingMetamodel mappingMetamodel,
|
||||
MetadataImplementor bootMetamodel,
|
||||
JpaStaticMetaModelPopulationSetting jpaStaticMetaModelPopulationSetting,
|
||||
JpaMetaModelPopulationSetting jpaMetaModelPopulationSetting,
|
||||
RuntimeModelCreationContext runtimeModelCreationContext) {
|
||||
this.jpaMetamodel = jpaMetamodel;
|
||||
this.metamodel = mappingMetamodel;
|
||||
this.knownMappedSuperclasses = bootMetamodel.getMappedSuperclassMappingsCopy();
|
||||
this.typeConfiguration = runtimeModelCreationContext.getTypeConfiguration();
|
||||
this.jpaStaticMetaModelPopulationSetting = jpaStaticMetaModelPopulationSetting;
|
||||
this.jpaMetaModelPopulationSetting = jpaMetaModelPopulationSetting;
|
||||
this.runtimeModelCreationContext = runtimeModelCreationContext;
|
||||
}
|
||||
|
||||
|
@ -287,13 +291,12 @@ public class MetadataContext {
|
|||
property
|
||||
);
|
||||
if ( attribute != null ) {
|
||||
( (AttributeContainer<Object>) jpaMapping ).getInFlightAccess().addAttribute( attribute );
|
||||
addAttribute( jpaMapping, attribute );
|
||||
if ( property.isNaturalIdentifier() ) {
|
||||
( ( AttributeContainer<Object>) jpaMapping ).getInFlightAccess()
|
||||
.applyNaturalIdAttribute( attribute );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
( (AttributeContainer<?>) jpaMapping ).getInFlightAccess().finishUp();
|
||||
|
@ -329,7 +332,7 @@ public class MetadataContext {
|
|||
}
|
||||
final PersistentAttribute<Object, ?> attribute = attributeFactory.buildAttribute( jpaType, property );
|
||||
if ( attribute != null ) {
|
||||
( (AttributeContainer<Object>) jpaType ).getInFlightAccess().addAttribute( attribute );
|
||||
addAttribute( jpaType, attribute );
|
||||
if ( property.isNaturalIdentifier() ) {
|
||||
( ( AttributeContainer<Object>) jpaType ).getInFlightAccess()
|
||||
.applyNaturalIdAttribute( attribute );
|
||||
|
@ -370,7 +373,7 @@ public class MetadataContext {
|
|||
final Property property = propertyItr.next();
|
||||
final PersistentAttribute<Object, ?> attribute = attributeFactory.buildAttribute( (ManagedDomainType<Object>) embeddable, property );
|
||||
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
|
||||
// 2) register the part (mapping role)
|
||||
|
|
|
@ -474,6 +474,7 @@ public class JpaMetamodelImpl implements JpaMetamodel, Serializable {
|
|||
mappingMetamodel,
|
||||
bootMetamodel,
|
||||
jpaStaticMetaModelPopulationSetting,
|
||||
jpaMetaModelPopulationSetting,
|
||||
runtimeModelCreationContext
|
||||
);
|
||||
|
||||
|
|
|
@ -158,6 +158,7 @@ import org.hibernate.metamodel.mapping.AttributeMapping;
|
|||
import org.hibernate.metamodel.mapping.AttributeMetadata;
|
||||
import org.hibernate.metamodel.mapping.AttributeMetadataAccess;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EmbeddableValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
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.StateArrayContributorMapping;
|
||||
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.CompoundNaturalIdMapping;
|
||||
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
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
//$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;
|
||||
|
||||
/**
|
|
@ -4,13 +4,14 @@
|
|||
* 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.test.formulajoin;
|
||||
package org.hibernate.orm.test.formulajoin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hibernate.Session;
|
||||
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.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
@ -23,10 +24,18 @@ import static org.junit.Assert.assertTrue;
|
|||
* @author Gavin King
|
||||
*/
|
||||
public class FormulaJoinTest extends BaseCoreFunctionalTestCase {
|
||||
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "formulajoin/Root.hbm.xml" };
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(Configuration configuration) {
|
||||
super.configure( configuration );
|
||||
configuration.setProperty( AvailableSettings.JPA_METAMODEL_POPULATION, "enabled" );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormulaJoin() {
|
||||
Session s = openSession();
|
||||
|
@ -50,7 +59,7 @@ public class FormulaJoinTest extends BaseCoreFunctionalTestCase {
|
|||
tx.commit();
|
||||
s.close();
|
||||
|
||||
if ( getDialect() instanceof PostgreSQLDialect || getDialect() instanceof PostgreSQL81Dialect ) return;
|
||||
if ( getDialect() instanceof PostgreSQLDialect ) return;
|
||||
|
||||
s = openSession();
|
||||
tx = s.beginTransaction();
|
||||
|
@ -83,10 +92,22 @@ public class FormulaJoinTest extends BaseCoreFunctionalTestCase {
|
|||
tx.commit();
|
||||
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();
|
||||
tx = s.beginTransaction();
|
||||
l = s.createQuery("from Detail d join fetch d.currentRoot.root m join fetch m.detail").list();
|
||||
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 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">
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
* 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.test.formulajoin;
|
||||
package org.hibernate.orm.test.formulajoin;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
Loading…
Reference in New Issue