Re-enabled additional tests and fixed IdClass issues

This commit is contained in:
Andrea Boriero 2020-11-18 12:55:18 +01:00
parent 693139c515
commit 1361b5108c
8 changed files with 113 additions and 66 deletions

View File

@ -166,8 +166,11 @@ public class MappingModelCreationHelper {
final StateArrayContributorMetadataAccess attributeMetadataAccess = getStateArrayContributorMetadataAccess(
propertyAccess
);
final Component bootIdDescriptor = (Component) bootEntityDescriptor.getIdentifier();
final Component idClass = bootEntityDescriptor.getIdentifierMapper();
Component bootIdDescriptor = bootEntityDescriptor.getDeclaredIdentifierMapper();
if ( bootIdDescriptor == null ) {
bootIdDescriptor = (Component) bootEntityDescriptor.getIdentifier();
}
final List<SingularAttributeMapping> idAttributeMappings = new ArrayList<>( bootIdDescriptor.getPropertySpan() );
//noinspection unchecked
@ -253,8 +256,8 @@ public class MappingModelCreationHelper {
attributeMetadataAccess,
rootTableName,
rootTableKeyColumnNames,
bootIdDescriptor,
bootCompositeDescriptor,
bootEntityDescriptor.getDeclaredIdentifierMapper(),
creationProcess
);
},

View File

@ -10,15 +10,20 @@ import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.MutableInteger;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.ManyToOne;
import org.hibernate.mapping.Property;
import org.hibernate.metamodel.internal.AbstractCompositeIdentifierMapping;
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
import org.hibernate.metamodel.mapping.EntityMappingType;
import org.hibernate.metamodel.mapping.SingularAttributeMapping;
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.type.ComponentType;
@ -76,21 +81,47 @@ public class NonAggregatedIdentifierMappingImpl extends AbstractCompositeIdentif
if ( entity instanceof HibernateProxy ) {
return ( (HibernateProxy) entity ).getHibernateLazyInitializer().getIdentifier();
}
final Serializable disassemble = bootIdClassDescriptor.getType().disassemble( entity, session, null );
return bootCidDescriptor.getType().assemble( disassemble, session, null );
final Serializable disassemble = bootCidDescriptor.getType().disassemble( entity, session, null );
return bootIdClassDescriptor.getType().assemble( disassemble, session, null );
}
@Override
public void setIdentifier(Object entity, Object id, SharedSessionContractImplementor session) {
final SessionFactoryImplementor factory = session.getFactory();
final Object[] propertyValues = ( (ComponentType) bootCidDescriptor.getType() )
final Object[] propertyValues = ( (ComponentType) bootIdClassDescriptor.getType() )
.getPropertyValues( id, session );
final MutableInteger index = new MutableInteger();
getAttributes().forEach(
attribute ->
attribute.getPropertyAccess()
.getSetter()
.set( entity, propertyValues[index.getAndIncrement()], factory )
attribute -> {
final int position = index.getAndIncrement();
Object propertyValue = propertyValues[position];
final Property property = bootIdClassDescriptor.getProperty( position );
if ( attribute instanceof ToOneAttributeMapping && !( property.getValue() instanceof ManyToOne ) ) {
final ToOneAttributeMapping toOneAttributeMapping = (ToOneAttributeMapping) attribute;
final EntityPersister entityPersister = toOneAttributeMapping.getEntityMappingType()
.getEntityPersister();
final EntityKey entityKey = session.generateEntityKey(
propertyValue,
entityPersister
);
final PersistenceContext persistenceContext = session.getPersistenceContext();
// it is conceivable there is a proxy, so check that first
propertyValue = persistenceContext.getProxy( entityKey );
if ( propertyValue == null ) {
// otherwise look for an initialized version
propertyValue = persistenceContext.getEntity( entityKey );
if ( propertyValue == null ) {
// get the association out of the entity itself
propertyValue = factory.getMetamodel()
.findEntityDescriptor( entity.getClass() )
.getPropertyValue( entity, toOneAttributeMapping.getAttributeName() );
}
}
}
attribute.getPropertyAccess()
.getSetter()
.set( entity, propertyValue, factory );
}
);
}

View File

@ -112,6 +112,7 @@ import org.hibernate.internal.util.collections.LockModeEnumMap;
import org.hibernate.jdbc.Expectation;
import org.hibernate.jdbc.Expectations;
import org.hibernate.jdbc.TooManyRowsAffectedException;
import org.hibernate.loader.PropertyPath;
import org.hibernate.loader.ast.internal.MultiIdLoaderStandard;
import org.hibernate.loader.ast.internal.Preparable;
import org.hibernate.loader.ast.internal.SingleIdEntityLoaderDynamicBatch;
@ -158,6 +159,7 @@ import org.hibernate.metamodel.mapping.StateArrayContributorMetadata;
import org.hibernate.metamodel.mapping.internal.BasicEntityIdentifierMappingImpl;
import org.hibernate.metamodel.mapping.internal.CompoundNaturalIdMapping;
import org.hibernate.metamodel.mapping.internal.DiscriminatedAssociationAttributeMapping;
import org.hibernate.metamodel.mapping.internal.EmbeddedAttributeMapping;
import org.hibernate.metamodel.mapping.internal.EntityDiscriminatorMappingImpl;
import org.hibernate.metamodel.mapping.internal.EntityRowIdMappingImpl;
import org.hibernate.metamodel.mapping.internal.EntityVersionMappingImpl;
@ -5309,8 +5311,8 @@ public abstract class AbstractEntityPersister
else {
final Object[] values = new Object[ getNumberOfAttributeMappings() ];
for ( int i = 0; i < attributeMappings.size(); i++ ) {
AttributeMapping attributeMapping = attributeMappings.get( i );
AttributeMetadataAccess attributeMetadataAccess = attributeMapping.getAttributeMetadataAccess();
final AttributeMapping attributeMapping = attributeMappings.get( i );
final AttributeMetadataAccess attributeMetadataAccess = attributeMapping.getAttributeMetadataAccess();
values[ i ] = attributeMetadataAccess
.resolveAttributeMetadata( this )
.getPropertyAccess()
@ -5334,13 +5336,27 @@ public abstract class AbstractEntityPersister
@Override
public Object getPropertyValue(Object object, String propertyName) {
for ( int i = 0; i < attributeMappings.size(); i++ ) {
if ( attributeMappings.get( i ).getAttributeName().equals( propertyName ) ) {
return attributeMappings.get( i ).getAttributeMetadataAccess()
final AttributeMapping attributeMapping = attributeMappings.get( i );
final String attributeName = attributeMapping.getAttributeName();
if ( attributeName.equals( propertyName ) ) {
return attributeMapping.getAttributeMetadataAccess()
.resolveAttributeMetadata( this )
.getPropertyAccess()
.getGetter()
.get( object );
}
else if ( attributeName.equals( PropertyPath.IDENTIFIER_MAPPER_PROPERTY ) && attributeMapping instanceof EmbeddedAttributeMapping ) {
final EmbeddedAttributeMapping embeddedAttributeMapping = (EmbeddedAttributeMapping) attributeMapping;
final AttributeMapping mapping = embeddedAttributeMapping.getMappedType()
.findAttributeMapping( propertyName );
if ( mapping != null ) {
return mapping.getAttributeMetadataAccess()
.resolveAttributeMetadata( this )
.getPropertyAccess()
.getGetter()
.get( object );
}
}
}
return null;
}

View File

@ -1,50 +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.id.idclass;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl;
import org.hibernate.cfg.Configuration;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
public class IdClassNamingStrategyTest extends BaseCoreFunctionalTestCase {
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { MyEntity.class };
}
@Override
protected void configure(Configuration configuration) {
/*
* With this implicit naming strategy, we got the following mapping:
*
* create table MyEntity (
* id_idA bigint not null,
* id_idB bigint not null,
* _identifierMapper_idA bigint not null, <-- ??
* _identifierMapper_idB bigint not null, <-- ??
* notes varchar(255),
* primary key (id_idA, id_idB)
* )
*/
configuration.setImplicitNamingStrategy( new ImplicitNamingStrategyComponentPathImpl() );
}
@Test
@TestForIssue(jiraKey = "HHH-14241")
public void test() {
inTransaction( ( session ) -> {
MyEntity entity = new MyEntity();
entity.setId( new MyEntityId( 739L, 777L ) );
session.persist( entity );
} );
}
}

View File

@ -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.id;
package org.hibernate.orm.test.id;
import java.io.Serializable;
import javax.persistence.Entity;

View File

@ -0,0 +1,47 @@
/*
* 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.test.id.idClass;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.junit.jupiter.api.Test;
import static org.hibernate.cfg.AvailableSettings.IMPLICIT_NAMING_STRATEGY;
@DomainModel(
annotatedClasses = MyEntity.class
)
@SessionFactory
/*
* With this implicit naming strategy, we got the following mapping:
*
* create table MyEntity (
* id_idA bigint not null,
* id_idB bigint not null,
* _identifierMapper_idA bigint not null, <-- ??
* _identifierMapper_idB bigint not null, <-- ??
* notes varchar(255),
* primary key (id_idA, id_idB)
* )
*/
@ServiceRegistry(settings = @ServiceRegistry.Setting(name = IMPLICIT_NAMING_STRATEGY, value = "component-path"))
public class IdClassNamingStrategyTest {
@Test
@TestForIssue(jiraKey = "HHH-14241")
public void test(SessionFactoryScope scope) {
scope.inTransaction( (session) -> {
MyEntity entity = new MyEntity();
entity.setId( new MyEntityId( 739L, 777L ) );
session.persist( entity );
} );
}
}

View File

@ -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.id.idclass;
package org.hibernate.test.id.idClass;
import javax.persistence.Entity;
import javax.persistence.Id;

View File

@ -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.id.idclass;
package org.hibernate.test.id.idClass;
import java.io.Serializable;
import java.util.Objects;