HHH-15837 - Cleanup the tuple package
This commit is contained in:
parent
ac32410438
commit
48c383121f
|
@ -94,6 +94,11 @@ public class BatchBuilderImpl implements BatchBuilder {
|
|||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyDetails getKeyDetails() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOptional() {
|
||||
return false;
|
||||
|
|
|
@ -190,7 +190,9 @@ public interface EntityMappingType
|
|||
// Inheritance
|
||||
|
||||
/**
|
||||
* Get the class that this class is mapped as a subclass of
|
||||
* Get the name of the entity that is the "super class" for this entity
|
||||
*
|
||||
* @see #getSuperMappingType
|
||||
*/
|
||||
default String getMappedSuperclass() {
|
||||
return getSuperMappingType().getEntityName();
|
||||
|
|
|
@ -29,16 +29,12 @@ import org.hibernate.type.descriptor.java.JavaType;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface ModelPart extends MappingModelExpressible {
|
||||
MappingType getPartMappingType();
|
||||
|
||||
JavaType<?> getJavaType();
|
||||
|
||||
String getPartName();
|
||||
|
||||
/**
|
||||
* @asciidoc
|
||||
*
|
||||
* The path for this fetchable back to an entity in the domain model.
|
||||
* The path for this fetchable back to an entity in the domain model. Acts as a unique
|
||||
* identifier for individual parts.
|
||||
*
|
||||
* Some examples:
|
||||
*
|
||||
|
@ -63,6 +59,43 @@ public interface ModelPart extends MappingModelExpressible {
|
|||
*/
|
||||
NavigableRole getNavigableRole();
|
||||
|
||||
/**
|
||||
* The local part name, which is generally the unqualified role name
|
||||
*/
|
||||
String getPartName();
|
||||
|
||||
/**
|
||||
* The type for this part.
|
||||
*/
|
||||
MappingType getPartMappingType();
|
||||
|
||||
/**
|
||||
* The Java type for this part. Generally equivalent to
|
||||
* {@link MappingType#getMappedJavaType()} relative to
|
||||
* {@link #getPartMappingType()}
|
||||
*/
|
||||
JavaType<?> getJavaType();
|
||||
|
||||
/**
|
||||
* Whether this model part describes something that physically
|
||||
* exists in the domain model.
|
||||
* <p/>
|
||||
* For example, take an entity defining its identifier with multiple
|
||||
* {@link jakarta.persistence.Id} attributes; a "non-aggregated" identifier.
|
||||
* Internally, Hibernate models the
|
||||
* {@linkplain EntityMappingType#getIdentifierMapping() identifier mapping}
|
||||
* for that entity as a virtual {@link EmbeddableMappingType}. The entity
|
||||
* might also define an {@link jakarta.persistence.IdClass}, but that is a
|
||||
* different mapping; in this case, the entity will have 2 mappings - one
|
||||
* physical (the {@link jakarta.persistence.IdClass}) and the other virtual
|
||||
* (the "non-aggregated" embeddable)
|
||||
* <p/>
|
||||
* Also indicates whether the part is castable to {@link VirtualModelPart}
|
||||
*/
|
||||
default boolean isVirtual() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a DomainResult for a specific reference to this ModelPart.
|
||||
*/
|
||||
|
|
|
@ -20,7 +20,15 @@ public interface TableDetails {
|
|||
String getTableName();
|
||||
|
||||
/**
|
||||
* Whether this table is the root for a given {@link ModelPartContainer}
|
||||
* Details about the primary-key of this table
|
||||
*/
|
||||
KeyDetails getKeyDetails();
|
||||
|
||||
/**
|
||||
* Whether this table is the root for a given {@link ModelPartContainer}.
|
||||
* <p/>
|
||||
* Only relevant for entity-mappings where this indicates whether this
|
||||
* table holds the entity's identifier.
|
||||
*/
|
||||
boolean isIdentifierTable();
|
||||
|
||||
|
@ -36,7 +44,7 @@ public interface TableDetails {
|
|||
/**
|
||||
* Group of columns defined on the primary key
|
||||
*/
|
||||
List<KeyColumn> getKeyColumns();
|
||||
List<? extends KeyColumn> getKeyColumns();
|
||||
|
||||
/**
|
||||
* Get a key column by relative position
|
||||
|
|
|
@ -7,9 +7,16 @@
|
|||
package org.hibernate.metamodel.mapping;
|
||||
|
||||
/**
|
||||
* Marker interface for parts of the application domain model that do not actually exist in the model classes
|
||||
* Marker interface for parts of the application domain model that do not actually
|
||||
* exist in the model classes.
|
||||
*
|
||||
* @see #isVirtual()
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface VirtualModelPart extends ModelPart {
|
||||
@Override
|
||||
default boolean isVirtual() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,6 +49,12 @@ public class CollectionTableMapping implements TableMapping {
|
|||
return tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyDetails getKeyDetails() {
|
||||
// todo (tuple-cleanup) : implement this
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isJoinTable() {
|
||||
return isJoinTable;
|
||||
}
|
||||
|
|
|
@ -1294,7 +1294,7 @@ public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
|
|||
if ( superMappingType == null ) {
|
||||
return getMappedTableDetails();
|
||||
}
|
||||
return superMappingType.getIdentifierTableDetails();
|
||||
return getRootEntityDescriptor().getIdentifierTableDetails();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.hibernate.jdbc.Expectation;
|
|||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.SelectableMapping;
|
||||
import org.hibernate.metamodel.mapping.TableDetails;
|
||||
import org.hibernate.sql.model.MutationType;
|
||||
import org.hibernate.sql.model.TableMapping;
|
||||
|
||||
|
@ -92,6 +93,11 @@ public class EntityTableMapping implements TableMapping {
|
|||
return tableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyDetails getKeyDetails() {
|
||||
return keyMapping;
|
||||
}
|
||||
|
||||
@Override public int getRelativePosition() {
|
||||
return relativePosition;
|
||||
}
|
||||
|
@ -203,7 +209,7 @@ public class EntityTableMapping implements TableMapping {
|
|||
void consume(Object jdbcValue, KeyColumn columnMapping);
|
||||
}
|
||||
|
||||
public static class KeyMapping {
|
||||
public static class KeyMapping implements KeyDetails {
|
||||
private final List<KeyColumn> keyColumns;
|
||||
|
||||
private final ModelPart identifierPart;
|
||||
|
@ -230,12 +236,34 @@ public class EntityTableMapping implements TableMapping {
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColumnCount() {
|
||||
return keyColumns.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<KeyColumn> getKeyColumns() {
|
||||
return keyColumns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyColumn getKeyColumn(int position) {
|
||||
return keyColumns.get( position );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachKeyColumn(KeyColumnConsumer consumer) {
|
||||
for ( int i = 0; i < keyColumns.size(); i++ ) {
|
||||
consumer.consume( i, keyColumns.get( i ) );
|
||||
}
|
||||
}
|
||||
|
||||
public void forEachKeyColumn(Consumer<KeyColumn> keyColumnConsumer) {
|
||||
keyColumns.forEach( keyColumnConsumer );
|
||||
}
|
||||
}
|
||||
|
||||
public static class KeyColumn implements SelectableMapping {
|
||||
public static class KeyColumn implements SelectableMapping, TableDetails.KeyColumn {
|
||||
private final String tableName;
|
||||
private final String columnName;
|
||||
private final String writeExpression;
|
||||
|
|
|
@ -41,6 +41,8 @@ import org.hibernate.engine.FetchTiming;
|
|||
import org.hibernate.engine.profile.FetchProfile;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.generator.Generator;
|
||||
import org.hibernate.generator.InMemoryGenerator;
|
||||
import org.hibernate.graph.spi.AppliedGraph;
|
||||
import org.hibernate.id.BulkInsertionCapableIdentifierGenerator;
|
||||
import org.hibernate.id.CompositeNestedGeneratedValueGenerator;
|
||||
|
@ -382,8 +384,6 @@ import org.hibernate.sql.results.graph.FetchableContainer;
|
|||
import org.hibernate.sql.results.graph.instantiation.internal.DynamicInstantiation;
|
||||
import org.hibernate.sql.results.internal.SqlSelectionImpl;
|
||||
import org.hibernate.sql.results.internal.StandardEntityGraphTraversalStateImpl;
|
||||
import org.hibernate.generator.Generator;
|
||||
import org.hibernate.generator.InMemoryGenerator;
|
||||
import org.hibernate.type.BasicType;
|
||||
import org.hibernate.type.CustomType;
|
||||
import org.hibernate.type.EnumType;
|
||||
|
|
|
@ -24,7 +24,6 @@ import org.hibernate.metamodel.mapping.JdbcMapping;
|
|||
import org.hibernate.orm.test.common.JournalingBatchObserver;
|
||||
import org.hibernate.resource.jdbc.spi.LogicalConnectionImplementor;
|
||||
import org.hibernate.sql.model.MutationType;
|
||||
import org.hibernate.sql.model.TableMapping;
|
||||
import org.hibernate.sql.model.jdbc.JdbcValueDescriptor;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
|
@ -32,7 +31,6 @@ import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
|||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.hibernate.jdbc.Expectations.NONE;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
@ -42,52 +40,6 @@ import static org.junit.Assert.assertTrue;
|
|||
*/
|
||||
public class BatchingTest extends BaseCoreFunctionalTestCase implements BatchKey {
|
||||
private final String SANDBOX_TBL = "SANDBOX_JDBC_TST";
|
||||
private final TableMapping SANDBOX_TBL_MAPPING = new TableMapping() {
|
||||
@Override
|
||||
public String getTableName() {
|
||||
return SANDBOX_TBL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRelativePosition() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOptional() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInverse() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIdentifierTable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutationDetails getInsertDetails() {
|
||||
return new MutationDetails( MutationType.INSERT, NONE, null, false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutationDetails getUpdateDetails() {
|
||||
return new MutationDetails( MutationType.UPDATE, NONE, null, false );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCascadeDeleteEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutationDetails getDeleteDetails() {
|
||||
return new MutationDetails( MutationType.DELETE, NONE, null, false );
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public int getBatchedStatementCount() {
|
||||
|
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* 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.mapping;
|
||||
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.TableDetails;
|
||||
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
import org.hibernate.testing.orm.domain.StandardDomainModel;
|
||||
import org.hibernate.testing.orm.domain.retail.CardPayment;
|
||||
import org.hibernate.testing.orm.domain.retail.Payment;
|
||||
import org.hibernate.testing.orm.domain.retail.Vendor;
|
||||
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.Test;
|
||||
|
||||
import jakarta.persistence.Basic;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Inheritance;
|
||||
import jakarta.persistence.InheritanceType;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @see org.hibernate.persister.entity.mutation.EntityTableMapping
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
standardModels = StandardDomainModel.RETAIL,
|
||||
annotatedClasses = {
|
||||
EntityTableMappingsTests.UnionRoot.class,
|
||||
EntityTableMappingsTests.UnionSub1.class,
|
||||
EntityTableMappingsTests.UnionSub2.class
|
||||
}
|
||||
)
|
||||
@SessionFactory(exportSchema = false)
|
||||
public class EntityTableMappingsTests {
|
||||
@Test
|
||||
public void testSingleTableHierarchyTableDetails(SessionFactoryScope scope) {
|
||||
final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory()
|
||||
.getRuntimeMetamodels()
|
||||
.getMappingMetamodel();
|
||||
verifyTableMappings(
|
||||
mappingMetamodel.getEntityDescriptor( Vendor.class ),
|
||||
"Vendor"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJoinedHierarchyTableDetails(SessionFactoryScope scope) {
|
||||
final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory()
|
||||
.getRuntimeMetamodels()
|
||||
.getMappingMetamodel();
|
||||
|
||||
// root
|
||||
verifyTableMappings(
|
||||
mappingMetamodel.getEntityDescriptor( Payment.class ),
|
||||
"payments"
|
||||
);
|
||||
|
||||
// sub
|
||||
verifyTableMappings(
|
||||
mappingMetamodel.getEntityDescriptor( CardPayment.class ),
|
||||
"payments",
|
||||
"CardPayment"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnionHierarchyTableDetails(SessionFactoryScope scope) {
|
||||
final MappingMetamodelImplementor mappingMetamodel = scope.getSessionFactory()
|
||||
.getRuntimeMetamodels()
|
||||
.getMappingMetamodel();
|
||||
|
||||
// root
|
||||
final EntityPersister rootDescriptor = mappingMetamodel.getEntityDescriptor( UnionRoot.class );
|
||||
verifyTableMappings(
|
||||
rootDescriptor,
|
||||
"UnionRoot",
|
||||
"UnionRoot"
|
||||
);
|
||||
|
||||
// sub1
|
||||
final EntityPersister sub1Descriptor = mappingMetamodel.getEntityDescriptor( UnionSub1.class );
|
||||
verifyTableMappings(
|
||||
sub1Descriptor,
|
||||
"unions_subs1",
|
||||
"unions_subs1"
|
||||
);
|
||||
|
||||
// sub2
|
||||
final EntityPersister sub2Descriptor = mappingMetamodel.getEntityDescriptor( UnionSub2.class );
|
||||
verifyTableMappings(
|
||||
sub2Descriptor,
|
||||
"unions_subs2",
|
||||
"unions_subs2"
|
||||
);
|
||||
}
|
||||
|
||||
private void verifyTableMappings(EntityMappingType entityDescriptor, String tableName) {
|
||||
verifyTableMappings( entityDescriptor, tableName, tableName );
|
||||
}
|
||||
|
||||
private void verifyTableMappings(
|
||||
EntityMappingType entityDescriptor,
|
||||
String identifierTableName,
|
||||
String mappedTableName) {
|
||||
final TableDetails idTable = entityDescriptor.getIdentifierTableDetails();
|
||||
assertThat( idTable.getTableName() ).isEqualTo( identifierTableName );
|
||||
assertThat( idTable.isIdentifierTable() ).isTrue();
|
||||
assertThat( idTable.getKeyDetails().getColumnCount() ).isEqualTo( 1 );
|
||||
assertThat( idTable.getKeyDetails().getKeyColumn( 0 ).getColumnName() ).isEqualTo( "id" );
|
||||
|
||||
final TableDetails mappedTable = entityDescriptor.getMappedTableDetails();
|
||||
assertThat( mappedTable.getTableName() ).isEqualTo( mappedTableName );
|
||||
assertThat( idTable.getKeyDetails().getColumnCount() ).isEqualTo( 1 );
|
||||
assertThat( idTable.getKeyDetails().getKeyColumn( 0 ).getColumnName() ).isEqualTo( "id" );
|
||||
if ( mappedTableName.equals( identifierTableName ) ) {
|
||||
assertThat( mappedTable.isIdentifierTable() ).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Entity( name = "UnionRoot" )
|
||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
||||
public static abstract class UnionRoot {
|
||||
@Id
|
||||
private Integer id;
|
||||
@Basic
|
||||
private String name;
|
||||
|
||||
private UnionRoot() {
|
||||
// for use by Hibernate
|
||||
}
|
||||
|
||||
public UnionRoot(Integer id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity( name = "UnionSub1" )
|
||||
@Table( name = "unions_subs1" )
|
||||
public static class UnionSub1 extends UnionRoot {
|
||||
private UnionSub1() {
|
||||
// for use by Hibernate
|
||||
}
|
||||
|
||||
public UnionSub1(Integer id, String name) {
|
||||
super( id, name );
|
||||
}
|
||||
}
|
||||
|
||||
@Entity( name = "UnionSub2" )
|
||||
@Table( name = "unions_subs2" )
|
||||
public static class UnionSub2 extends UnionRoot {
|
||||
private UnionSub2() {
|
||||
// for use by Hibernate
|
||||
}
|
||||
|
||||
public UnionSub2(Integer id, String name) {
|
||||
super( id, name );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -651,15 +651,11 @@ public class ValidityAuditStrategy implements AuditStrategy {
|
|||
}
|
||||
|
||||
private String getUpdateTableName(Queryable rootEntity, Queryable rootAuditEntity, Queryable auditEntity) {
|
||||
if ( UnionSubclassEntityPersister.class.isInstance( rootEntity ) ) {
|
||||
// This is the condition causing all the problems of the generated SQL update;
|
||||
// the problem being that we currently try to update the inline view made of the union query.
|
||||
//
|
||||
// This is hacky to get the root table name for the union subclass style entities because
|
||||
// it relies on internal behavior of UnionSubclassEntityPersister.
|
||||
return auditEntity.getSubclassTableName( 0 );
|
||||
if ( rootEntity instanceof UnionSubclassEntityPersister ) {
|
||||
// we need to specially handle union-subclass mappings
|
||||
return auditEntity.getMappedTableDetails().getTableName();
|
||||
}
|
||||
return rootAuditEntity.getTableName();
|
||||
return rootAuditEntity.getMappedTableDetails().getTableName();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue