HHH-13725 ToMany FkDescriptor creation and circular fetch detecion
This commit is contained in:
parent
aa3ff4507d
commit
343dd979ba
|
@ -13,7 +13,7 @@ package org.hibernate.metamodel.mapping;
|
|||
public interface ColumnConsumer {
|
||||
// todo (6.0) : pass values `updateable`, `checkable`, etc
|
||||
void accept(
|
||||
String columnExpression,
|
||||
String containingTableExpression,
|
||||
String columnExpression,
|
||||
JdbcMapping jdbcMapping);
|
||||
}
|
||||
|
|
|
@ -35,4 +35,8 @@ public interface InFlightEntityMappingType extends EntityMappingType {
|
|||
default void prepareMappingModel(MappingModelCreationProcess creationProcess) {
|
||||
// by default do nothing - support for legacy impls
|
||||
}
|
||||
|
||||
default void finishMappingModelInitialization(MappingModelCreationProcess creationProcess) {
|
||||
// by default do nothing
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,13 +13,9 @@ import java.util.SortedMap;
|
|||
import java.util.SortedSet;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.LockMode;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.NotYetImplementedFor6Exception;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.boot.model.naming.Identifier;
|
||||
import org.hibernate.collection.internal.StandardArraySemantics;
|
||||
import org.hibernate.collection.internal.StandardBagSemantics;
|
||||
import org.hibernate.collection.internal.StandardIdentifierBagSemantics;
|
||||
|
@ -911,58 +907,95 @@ public class MappingModelCreationHelper {
|
|||
);
|
||||
}
|
||||
|
||||
private static ForeignKeyDescriptor interpretKeyDescriptor(
|
||||
public static void interpretKeyDescriptor(
|
||||
SingularAssociationAttributeMapping attributeMapping,
|
||||
Property bootProperty,
|
||||
ToOne bootValueMapping,
|
||||
EntityPersister referencedEntityDescriptor,
|
||||
EntityPersister declaringEntityDescriptor,
|
||||
Dialect dialect,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
|
||||
if ( attributeMapping.getForeignKeyDescriptor() != null ) {
|
||||
return;
|
||||
}
|
||||
EntityPersister referencedEntityDescriptor = creationProcess.getEntityPersister(
|
||||
bootValueMapping.getReferencedEntityName() );
|
||||
final ModelPart fkTarget;
|
||||
final ForeignKeyDirection foreignKeyDirection = ( (AssociationType) bootValueMapping.getType() ).getForeignKeyDirection();
|
||||
referencedEntityDescriptor.prepareMappingModel( creationProcess );
|
||||
if ( bootValueMapping.isReferenceToPrimaryKey() ) {
|
||||
referencedEntityDescriptor.prepareMappingModel( creationProcess );
|
||||
fkTarget = referencedEntityDescriptor.getIdentifierMapping();
|
||||
}
|
||||
else {
|
||||
fkTarget = referencedEntityDescriptor.findSubPart( bootValueMapping.getReferencedPropertyName() );
|
||||
fkTarget = declaringEntityDescriptor.getIdentifierMapping();
|
||||
}
|
||||
|
||||
final JdbcServices jdbcServices = creationProcess.getCreationContext().getSessionFactory().getJdbcServices();
|
||||
|
||||
if ( fkTarget instanceof BasicValuedModelPart ) {
|
||||
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
|
||||
final String keyColumnExpression;
|
||||
final String keyTableIdentifierExpression;
|
||||
if ( bootValueMapping.isReferenceToPrimaryKey() ) {
|
||||
final Iterator<Selectable> columnIterator = bootValueMapping.getColumnIterator();
|
||||
if ( columnIterator.hasNext() ) {
|
||||
keyColumnExpression = columnIterator.next().getText( dialect );
|
||||
}
|
||||
else {
|
||||
// case of ToOne with @PrimaryKeyJoinColumn
|
||||
keyColumnExpression = bootValueMapping.getTable().getColumn( 0 ).getName();
|
||||
}
|
||||
|
||||
final Iterator<Selectable> columnIterator = bootValueMapping.getColumnIterator();
|
||||
String keyColumnExpression;
|
||||
keyTableIdentifierExpression = creationProcess.getCreationContext()
|
||||
.getBootstrapContext()
|
||||
.getMetadataBuildingOptions()
|
||||
.getPhysicalNamingStrategy().toPhysicalTableName(
|
||||
bootValueMapping.getTable().getNameIdentifier(),
|
||||
jdbcServices.getJdbcEnvironment()
|
||||
).getText();
|
||||
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
|
||||
ForeignKeyDescriptor foreignKeyDescriptor = new SimpleForeignKeyDescriptor(
|
||||
foreignKeyDirection,
|
||||
keyTableIdentifierExpression,
|
||||
keyColumnExpression,
|
||||
simpleFkTarget.getContainingTableExpression(),
|
||||
simpleFkTarget.getMappedColumnExpression(),
|
||||
simpleFkTarget.getJdbcMapping()
|
||||
|
||||
);
|
||||
attributeMapping.setForeignKeyDescriptor( foreignKeyDescriptor );
|
||||
|
||||
final Identifier tableIdentifier = creationProcess.getCreationContext()
|
||||
.getBootstrapContext()
|
||||
.getMetadataBuildingOptions()
|
||||
.getPhysicalNamingStrategy().toPhysicalTableName(
|
||||
bootValueMapping.getTable().getNameIdentifier(),
|
||||
jdbcServices.getJdbcEnvironment()
|
||||
);
|
||||
if ( columnIterator.hasNext() ) {
|
||||
keyColumnExpression = columnIterator.next().getText( dialect );
|
||||
}
|
||||
else {
|
||||
// case of ToOne with @PrimaryKeyJoinColumn
|
||||
keyColumnExpression = bootValueMapping.getTable().getColumn( 0 ).getName();
|
||||
SingularAssociationAttributeMapping subPart = (SingularAssociationAttributeMapping) referencedEntityDescriptor
|
||||
.findSubPart( bootValueMapping.getReferencedPropertyName() );
|
||||
ForeignKeyDescriptor foreignKeyDescriptor = subPart.getForeignKeyDescriptor();
|
||||
|
||||
if ( foreignKeyDescriptor == null ) {
|
||||
PersistentClass entityBinding = creationProcess.getCreationContext()
|
||||
.getBootModel()
|
||||
.getEntityBinding(
|
||||
referencedEntityDescriptor.getEntityName() );
|
||||
Property property = entityBinding.getProperty( bootValueMapping.getReferencedPropertyName() );
|
||||
interpretKeyDescriptor(
|
||||
subPart,
|
||||
property,
|
||||
(ToOne) property.getValue(),
|
||||
referencedEntityDescriptor,
|
||||
dialect,
|
||||
creationProcess
|
||||
);
|
||||
attributeMapping.setForeignKeyDescriptor( subPart.getForeignKeyDescriptor() );
|
||||
|
||||
}
|
||||
else {
|
||||
attributeMapping.setForeignKeyDescriptor( foreignKeyDescriptor );
|
||||
}
|
||||
}
|
||||
return new SimpleForeignKeyDescriptor(
|
||||
((AssociationType)bootValueMapping.getType()).getForeignKeyDirection(),
|
||||
tableIdentifier.getText(),
|
||||
keyColumnExpression,
|
||||
simpleFkTarget.getContainingTableExpression(),
|
||||
simpleFkTarget.getMappedColumnExpression(),
|
||||
simpleFkTarget.getJdbcMapping()
|
||||
}
|
||||
else {
|
||||
throw new NotYetImplementedFor6Exception(
|
||||
"Support for composite foreign-keys not yet implemented: " +
|
||||
bootProperty.getPersistentClass().getEntityName() + " -> " + bootProperty.getName()
|
||||
);
|
||||
}
|
||||
|
||||
throw new NotYetImplementedFor6Exception(
|
||||
"Support for composite foreign-keys not yet implemented: " +
|
||||
bootProperty.getPersistentClass().getEntityName() + " -> " + bootProperty.getName()
|
||||
);
|
||||
}
|
||||
|
||||
private static CollectionPart interpretMapKey(
|
||||
|
@ -1140,18 +1173,6 @@ public class MappingModelCreationHelper {
|
|||
creationProcess
|
||||
);
|
||||
SessionFactoryImplementor sessionFactory = creationProcess.getCreationContext().getSessionFactory();
|
||||
final Dialect dialect = sessionFactory
|
||||
.getJdbcServices()
|
||||
.getJdbcEnvironment()
|
||||
.getDialect();
|
||||
|
||||
final ForeignKeyDescriptor foreignKeyDescriptor = interpretKeyDescriptor(
|
||||
bootProperty,
|
||||
value,
|
||||
entityPersister,
|
||||
dialect,
|
||||
creationProcess
|
||||
);
|
||||
|
||||
final AssociationType type = (AssociationType) bootProperty.getType();
|
||||
final FetchStyle fetchStyle = FetchStrategyHelper
|
||||
|
@ -1168,8 +1189,7 @@ public class MappingModelCreationHelper {
|
|||
return new SingularAssociationAttributeMapping(
|
||||
attrName,
|
||||
stateArrayPosition,
|
||||
bootProperty.getValue().isNullable(),
|
||||
foreignKeyDescriptor,
|
||||
(ToOne) bootProperty.getValue(),
|
||||
stateArrayContributorMetadataAccess,
|
||||
fetchStrategy,
|
||||
entityPersister,
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
package org.hibernate.metamodel.mapping.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -67,6 +66,12 @@ public class MappingModelCreationProcess {
|
|||
entityPersister.prepareMappingModel( this );
|
||||
}
|
||||
|
||||
for ( EntityPersister entityPersister : entityPersisterMap.values() ) {
|
||||
currentlyProcessingRole = entityPersister.getEntityName();
|
||||
|
||||
entityPersister.finishMappingModelInitialization( this );
|
||||
}
|
||||
|
||||
while ( postInitCallbacks != null && ! postInitCallbacks.isEmpty() ) {
|
||||
// copy to avoid CCME
|
||||
final ArrayList<PostInitCallback> copy = new ArrayList<>( new ArrayList<>( postInitCallbacks ) );
|
||||
|
|
|
@ -9,14 +9,12 @@ package org.hibernate.metamodel.mapping.internal;
|
|||
import org.hibernate.LockMode;
|
||||
import org.hibernate.engine.FetchStrategy;
|
||||
import org.hibernate.engine.FetchTiming;
|
||||
import org.hibernate.mapping.ToOne;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.ManagedMappingType;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.StateArrayContributorMetadataAccess;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.persister.collection.CollectionPersister;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.property.access.spi.PropertyAccess;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
|
@ -39,6 +37,7 @@ import org.hibernate.sql.results.internal.domain.entity.EntityFetch;
|
|||
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||
import org.hibernate.sql.results.spi.Fetch;
|
||||
import org.hibernate.sql.results.spi.FetchParent;
|
||||
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
|
@ -47,13 +46,13 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
|
|||
implements EntityValuedModelPart, TableGroupJoinProducer {
|
||||
private final String sqlAliasStem;
|
||||
private final boolean isNullable;
|
||||
private final ForeignKeyDescriptor foreignKeyDescriptor;
|
||||
private ForeignKeyDescriptor foreignKeyDescriptor;
|
||||
private final String referencedPropertyName;
|
||||
|
||||
public SingularAssociationAttributeMapping(
|
||||
String name,
|
||||
int stateArrayPosition,
|
||||
boolean isNullable,
|
||||
ForeignKeyDescriptor foreignKeyDescriptor,
|
||||
ToOne value,
|
||||
StateArrayContributorMetadataAccess attributeMetadataAccess,
|
||||
FetchStrategy mappedFetchStrategy,
|
||||
EntityMappingType type,
|
||||
|
@ -69,10 +68,18 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
|
|||
propertyAccess
|
||||
);
|
||||
this.sqlAliasStem = SqlAliasStemHelper.INSTANCE.generateStemFromAttributeName( name );
|
||||
this.isNullable = isNullable;
|
||||
this.isNullable = value.isNullable();
|
||||
referencedPropertyName = value.getReferencedPropertyName();
|
||||
}
|
||||
|
||||
public void setForeignKeyDescriptor(ForeignKeyDescriptor foreignKeyDescriptor){
|
||||
this.foreignKeyDescriptor = foreignKeyDescriptor;
|
||||
}
|
||||
|
||||
public ForeignKeyDescriptor getForeignKeyDescriptor(){
|
||||
return this.foreignKeyDescriptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMappingType getMappedTypeDescriptor() {
|
||||
return (EntityMappingType) super.getMappedTypeDescriptor();
|
||||
|
@ -227,38 +234,42 @@ public class SingularAssociationAttributeMapping extends AbstractSingularAttribu
|
|||
|
||||
@Override
|
||||
public boolean isCircular(FetchParent fetchParent, SqlAstProcessingState creationState) {
|
||||
final NavigablePath navigablePath = fetchParent.getNavigablePath();
|
||||
|
||||
final NavigablePath parent = navigablePath.getParent();
|
||||
if ( parent == null ) {
|
||||
final NavigablePath panentNaviblePath = fetchParent.getNavigablePath();
|
||||
final NavigablePath parentParentNavigablePath = panentNaviblePath.getParent();
|
||||
if ( parentParentNavigablePath == null ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
final String entityName = getMappedTypeDescriptor().getEntityName();
|
||||
if ( parent.getLocalName().equals( entityName ) ) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
NavigablePath parentOfParent = parent.getParent();
|
||||
if ( parentOfParent == null ) {
|
||||
return false;
|
||||
|
||||
if ( panentNaviblePath.getLocalName().equals( referencedPropertyName ) ) {
|
||||
if ( parentParentNavigablePath.getLocalName().equals( entityName ) ) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if ( parentOfParent.getParent() != null ) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
final EntityPersister entityDescriptor = creationState.getSqlAstCreationState()
|
||||
.getCreationContext()
|
||||
.getDomainModel()
|
||||
.findEntityDescriptor( parentOfParent.getFullPath() );
|
||||
final String parentEntityName = entityDescriptor.findSubPart( parent.getLocalName() ).getJavaTypeDescriptor()
|
||||
.getJavaType()
|
||||
.getName();
|
||||
if ( parentEntityName.equals( entityName ) ) {
|
||||
return true;
|
||||
}
|
||||
// need to check if panentNaviblePath.getParent()
|
||||
// FetchParent fetchParent1 = fetchParentByNavigableFullPath.get( parentParentNavigablePath.getFullPath() );
|
||||
final JavaTypeDescriptor resultJavaTypeDescriptor = fetchParent.getResultJavaTypeDescriptor();
|
||||
if ( getEntityMappingType().getJavaTypeDescriptor().getJavaType()
|
||||
.equals( resultJavaTypeDescriptor.getJavaType() ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( parentParentNavigablePath.getLocalName().equals( entityName ) ) {
|
||||
return true;
|
||||
}
|
||||
JavaTypeDescriptor parentParentJavaTypeDescriptor = creationState.getSqlAstCreationState()
|
||||
.getFromClauseAccess()
|
||||
.findTableGroup( parentParentNavigablePath )
|
||||
.getModelPart()
|
||||
.getJavaTypeDescriptor();
|
||||
|
||||
if ( getEntityMappingType().getJavaTypeDescriptor().getJavaType()
|
||||
.equals( parentParentJavaTypeDescriptor.getJavaType() ) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -134,6 +134,7 @@ import org.hibernate.mapping.RootClass;
|
|||
import org.hibernate.mapping.Selectable;
|
||||
import org.hibernate.mapping.Subclass;
|
||||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.mapping.ToOne;
|
||||
import org.hibernate.metadata.ClassMetadata;
|
||||
import org.hibernate.metamodel.RepresentationMode;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
|
@ -143,6 +144,7 @@ import org.hibernate.metamodel.mapping.EntityDiscriminatorMapping;
|
|||
import org.hibernate.metamodel.mapping.EntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.EntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.EntityVersionMapping;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.NaturalIdMapping;
|
||||
|
@ -153,6 +155,7 @@ import org.hibernate.metamodel.mapping.internal.EntityDiscriminatorMappingImpl;
|
|||
import org.hibernate.metamodel.mapping.internal.InFlightEntityMappingType;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationHelper;
|
||||
import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess;
|
||||
import org.hibernate.metamodel.mapping.internal.SingularAssociationAttributeMapping;
|
||||
import org.hibernate.metamodel.model.domain.NavigableRole;
|
||||
import org.hibernate.metamodel.spi.EntityRepresentationStrategy;
|
||||
import org.hibernate.metamodel.spi.RuntimeModelCreationContext;
|
||||
|
@ -6213,6 +6216,26 @@ public abstract class AbstractEntityPersister
|
|||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finishMappingModelInitialization(MappingModelCreationProcess creationProcess) {
|
||||
singularAssociationsToFinilize.forEach( (property, singularAssociationAttributeMapping) -> {
|
||||
final Dialect dialect = creationProcess.getCreationContext()
|
||||
.getSessionFactory()
|
||||
.getJdbcServices()
|
||||
.getJdbcEnvironment()
|
||||
.getDialect();
|
||||
|
||||
MappingModelCreationHelper.interpretKeyDescriptor(
|
||||
singularAssociationAttributeMapping,
|
||||
property,
|
||||
(ToOne) property.getValue(),
|
||||
this,
|
||||
dialect,
|
||||
creationProcess
|
||||
);
|
||||
} );
|
||||
}
|
||||
|
||||
protected static SqmMultiTableMutationStrategy interpretSqmMultiTableStrategy(
|
||||
AbstractEntityPersister entityMappingDescriptor,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
|
@ -6378,6 +6401,8 @@ public abstract class AbstractEntityPersister
|
|||
throw new NotYetImplementedFor6Exception( AbstractEntityPersister.class );
|
||||
}
|
||||
|
||||
Map<Property,SingularAssociationAttributeMapping> singularAssociationsToFinilize = new HashMap<>( );
|
||||
|
||||
private AttributeMapping generateNonIdAttributeMapping(
|
||||
NonIdentifierAttribute tupleAttrDefinition,
|
||||
Property bootProperty,
|
||||
|
@ -6438,7 +6463,7 @@ public abstract class AbstractEntityPersister
|
|||
);
|
||||
}
|
||||
else if ( attrType instanceof EntityType ) {
|
||||
return MappingModelCreationHelper.buildSingularAssociationAttributeMapping(
|
||||
SingularAssociationAttributeMapping attributeMapping = MappingModelCreationHelper.buildSingularAssociationAttributeMapping(
|
||||
attrName,
|
||||
stateArrayPosition,
|
||||
bootProperty,
|
||||
|
@ -6448,6 +6473,8 @@ public abstract class AbstractEntityPersister
|
|||
tupleAttrDefinition.getCascadeStyle(),
|
||||
creationProcess
|
||||
);
|
||||
singularAssociationsToFinilize.put( bootProperty,attributeMapping );
|
||||
return attributeMapping;
|
||||
}
|
||||
|
||||
// todo (6.0) : for now ignore any non basic-typed attributes
|
||||
|
|
|
@ -19,7 +19,10 @@ import org.hibernate.sql.results.internal.domain.BiDirectionalFetchImpl;
|
|||
*/
|
||||
public class CircularFetchDetector {
|
||||
|
||||
public Fetch findBiDirectionalFetch(FetchParent fetchParent, Fetchable fetchable, SqlAstProcessingState creationState) {
|
||||
public Fetch findBiDirectionalFetch(
|
||||
FetchParent fetchParent,
|
||||
Fetchable fetchable,
|
||||
SqlAstProcessingState creationState) {
|
||||
if ( !fetchable.isCircular( fetchParent, creationState ) ) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.manytoone;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.SingularAssociationAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
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.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
ManyToOneJoinTableTest.SimpleEntity.class,
|
||||
ManyToOneJoinTableTest.OtherEntity.class,
|
||||
ManyToOneJoinTableTest.AnotherEntity.class
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory
|
||||
public class ManyToOneJoinTableTest {
|
||||
|
||||
@Test
|
||||
public void basicTest(SessionFactoryScope scope) {
|
||||
final EntityPersister otherDescriptor = scope.getSessionFactory()
|
||||
.getMetamodel()
|
||||
.findEntityDescriptor( OtherEntity.class );
|
||||
|
||||
final ModelPart simpleEntityAssociation = otherDescriptor.findSubPart( "simpleEntity" );
|
||||
|
||||
assertThat( simpleEntityAssociation, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
final SingularAssociationAttributeMapping simpleAttributeMapping = (SingularAssociationAttributeMapping) simpleEntityAssociation;
|
||||
|
||||
ForeignKeyDescriptor foreignKeyDescriptor = simpleAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "other_simple" ) );
|
||||
assertThat( keyColumn, is( "RHS_ID" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "simple_entity" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
|
||||
final ModelPart anotherEntityAssociation = otherDescriptor.findSubPart( "anotherEntity" );
|
||||
|
||||
assertThat( anotherEntityAssociation, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
final SingularAssociationAttributeMapping anotherAttributeMapping = (SingularAssociationAttributeMapping) anotherEntityAssociation;
|
||||
|
||||
foreignKeyDescriptor = anotherAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "other_another" ) );
|
||||
assertThat( keyColumn, is( "RHS_ID" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "another_entity" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
|
||||
|
||||
final EntityPersister simpleDescriptor = scope.getSessionFactory()
|
||||
.getMetamodel()
|
||||
.findEntityDescriptor( SimpleEntity.class );
|
||||
|
||||
ModelPart otherEntityEntityAssociation = simpleDescriptor.findSubPart( "other" );
|
||||
|
||||
assertThat( otherEntityEntityAssociation, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
SingularAssociationAttributeMapping otherAttributeMapping = (SingularAssociationAttributeMapping) otherEntityEntityAssociation;
|
||||
|
||||
foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "other_simple" ) );
|
||||
assertThat( keyColumn, is( "LHS_ID" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "other_entity" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
|
||||
|
||||
final EntityPersister anotherDescriptor = scope.getSessionFactory()
|
||||
.getMetamodel()
|
||||
.findEntityDescriptor( AnotherEntity.class );
|
||||
|
||||
otherEntityEntityAssociation = anotherDescriptor.findSubPart( "other" );
|
||||
|
||||
assertThat( otherEntityEntityAssociation, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
otherAttributeMapping = (SingularAssociationAttributeMapping) otherEntityEntityAssociation;
|
||||
|
||||
foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "another_entity" ) );
|
||||
assertThat( keyColumn, is( "other_id" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "other_entity" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Entity(name = "OtherEntity")
|
||||
@Table(name = "other_entity")
|
||||
public static class OtherEntity {
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
private SimpleEntity simpleEntity;
|
||||
|
||||
private AnotherEntity anotherEntity;
|
||||
|
||||
@Id
|
||||
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;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
@JoinTable(name = "other_simple",
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "LHS_ID")
|
||||
},
|
||||
inverseJoinColumns = {
|
||||
@JoinColumn(name = "RHS_ID")
|
||||
})
|
||||
public SimpleEntity getSimpleEntity() {
|
||||
return simpleEntity;
|
||||
}
|
||||
|
||||
public void setSimpleEntity(SimpleEntity simpleEntity) {
|
||||
this.simpleEntity = simpleEntity;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
@JoinTable(name = "other_another",
|
||||
joinColumns = {
|
||||
@JoinColumn(name = "LHS_ID")
|
||||
},
|
||||
inverseJoinColumns = {
|
||||
@JoinColumn(name = "RHS_ID")
|
||||
})
|
||||
public AnotherEntity getAnotherEntity() {
|
||||
return anotherEntity;
|
||||
}
|
||||
|
||||
public void setAnotherEntity(AnotherEntity anotherEntity) {
|
||||
this.anotherEntity = anotherEntity;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "SimpleEntity")
|
||||
@Table(name = "simple_entity")
|
||||
public static class SimpleEntity {
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
private OtherEntity other;
|
||||
|
||||
@Id
|
||||
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;
|
||||
}
|
||||
|
||||
@OneToOne(mappedBy = "simpleEntity")
|
||||
public OtherEntity getOther() {
|
||||
return other;
|
||||
}
|
||||
|
||||
public void setOther(OtherEntity other) {
|
||||
this.other = other;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "AnotherEntity")
|
||||
@Table(name = "another_entity")
|
||||
public static class AnotherEntity {
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
private OtherEntity other;
|
||||
|
||||
@Id
|
||||
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;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
public OtherEntity getOther() {
|
||||
return other;
|
||||
}
|
||||
|
||||
public void setOther(OtherEntity other) {
|
||||
this.other = other;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.manytoone;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.SingularAssociationAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
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.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
ManyToOneTest.SimpleEntity.class,
|
||||
ManyToOneTest.OtherEntity.class
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory
|
||||
public class ManyToOneTest {
|
||||
|
||||
@Test
|
||||
public void basicTest(SessionFactoryScope scope) {
|
||||
final EntityPersister otherDescriptor = scope.getSessionFactory()
|
||||
.getMetamodel()
|
||||
.findEntityDescriptor( OtherEntity.class );
|
||||
|
||||
final ModelPart simpleEntityAssociation = otherDescriptor.findSubPart( "simpleEntity" );
|
||||
|
||||
assertThat( simpleEntityAssociation, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
final SingularAssociationAttributeMapping childAttributeMapping = (SingularAssociationAttributeMapping) simpleEntityAssociation;
|
||||
|
||||
ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "other_entity" ) );
|
||||
assertThat( keyColumn, is( "simple_entity_id" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "simple_entity" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Entity(name = "OtherEntity")
|
||||
@Table(name = "other_entity")
|
||||
public static class OtherEntity {
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
private SimpleEntity simpleEntity;
|
||||
|
||||
@Id
|
||||
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;
|
||||
}
|
||||
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "simple_entity_id")
|
||||
public SimpleEntity getSimpleEntity() {
|
||||
return simpleEntity;
|
||||
}
|
||||
|
||||
public void setSimpleEntity(SimpleEntity simpleEntity) {
|
||||
this.simpleEntity = simpleEntity;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Entity(name = "SimpleEntity")
|
||||
@Table(name = "simple_entity")
|
||||
public static class SimpleEntity {
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
@Id
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.onetoone;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.SingularAssociationAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
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.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
EntityWithBidirectionalAssociationTest.Parent.class,
|
||||
EntityWithBidirectionalAssociationTest.Child.class
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory
|
||||
public class EntityWithBidirectionalAssociationTest {
|
||||
@Test
|
||||
public void basicTest(SessionFactoryScope scope) {
|
||||
final EntityPersister parentDescriptor = scope.getSessionFactory()
|
||||
.getMetamodel()
|
||||
.findEntityDescriptor( Parent.class );
|
||||
|
||||
final ModelPart childAssociation = parentDescriptor.findSubPart( "child" );
|
||||
|
||||
assertThat( childAssociation, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
final SingularAssociationAttributeMapping childAttributeMapping = (SingularAssociationAttributeMapping) childAssociation;
|
||||
|
||||
ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "PARENT" ) );
|
||||
assertThat( keyColumn, is( "child_id" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "CHILD" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
|
||||
final EntityPersister childDescriptor = scope.getSessionFactory()
|
||||
.getMetamodel()
|
||||
.findEntityDescriptor( Child.class );
|
||||
|
||||
final ModelPart parentAssociation = childDescriptor.findSubPart( "parent" );
|
||||
|
||||
assertThat( parentAssociation, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
final SingularAssociationAttributeMapping parentAttributeMapping = (SingularAssociationAttributeMapping) parentAssociation;
|
||||
|
||||
foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "PARENT" ) );
|
||||
assertThat( keyColumn, is( "child_id" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "CHILD" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Entity(name = "Parent")
|
||||
@Table(name = "PARENT")
|
||||
public static class Parent {
|
||||
private Integer id;
|
||||
|
||||
private String description;
|
||||
private Child child;
|
||||
|
||||
Parent() {
|
||||
}
|
||||
|
||||
public Parent(Integer id, String description) {
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Id
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@OneToOne
|
||||
public Child getChild() {
|
||||
return child;
|
||||
}
|
||||
|
||||
public void setChild(Child other) {
|
||||
this.child = other;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Entity(name = "Child")
|
||||
@Table(name = "CHILD")
|
||||
public static class Child {
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
private Parent parent;
|
||||
|
||||
Child() {
|
||||
}
|
||||
|
||||
Child(Integer id, Parent parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
this.parent.setChild( this );
|
||||
}
|
||||
|
||||
@Id
|
||||
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;
|
||||
}
|
||||
|
||||
@OneToOne(mappedBy = "child")
|
||||
public Parent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(Parent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.onetoone;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.SingularAssociationAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
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.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
EntityWithOneBidirectionalJoinTableAssociationTest.Parent.class,
|
||||
EntityWithOneBidirectionalJoinTableAssociationTest.Child.class,
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory
|
||||
public class EntityWithOneBidirectionalJoinTableAssociationTest {
|
||||
@Test
|
||||
public void basicTest(SessionFactoryScope scope) {
|
||||
final EntityPersister parentDescriptor = scope.getSessionFactory()
|
||||
.getMetamodel()
|
||||
.findEntityDescriptor( Parent.class );
|
||||
|
||||
final ModelPart childAssociation = parentDescriptor.findSubPart( "child" );
|
||||
|
||||
assertThat( childAssociation, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
final SingularAssociationAttributeMapping childAttributeMapping = (SingularAssociationAttributeMapping) childAssociation;
|
||||
|
||||
ForeignKeyDescriptor foreignKeyDescriptor = childAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "PARENT_CHILD" ) );
|
||||
assertThat( keyColumn, is( "child_id" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "CHILD" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
|
||||
final EntityPersister childDescriptor = scope.getSessionFactory()
|
||||
.getMetamodel()
|
||||
.findEntityDescriptor( Child.class );
|
||||
|
||||
final ModelPart parentAssociation = childDescriptor.findSubPart( "parent" );
|
||||
|
||||
assertThat( parentAssociation, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
final SingularAssociationAttributeMapping parentAttributeMapping = (SingularAssociationAttributeMapping) parentAssociation;
|
||||
|
||||
foreignKeyDescriptor = parentAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "PARENT_CHILD" ) );
|
||||
assertThat( keyColumn, is( "parent_id" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "PARENT" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
}
|
||||
|
||||
@Entity(name = "Parent")
|
||||
@Table(name = "PARENT")
|
||||
public static class Parent {
|
||||
private Integer id;
|
||||
|
||||
private String description;
|
||||
private Child child;
|
||||
|
||||
Parent() {
|
||||
}
|
||||
|
||||
public Parent(Integer id, String description) {
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Id
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@OneToOne
|
||||
@JoinTable(name = "PARENT_CHILD", inverseJoinColumns = @JoinColumn(name = "child_id"), joinColumns = @JoinColumn(name = "parent_id"))
|
||||
public Child getChild() {
|
||||
return child;
|
||||
}
|
||||
|
||||
public void setChild(Child other) {
|
||||
this.child = other;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Entity(name = "Child")
|
||||
@Table(name = "CHILD")
|
||||
public static class Child {
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
private Parent parent;
|
||||
|
||||
Child() {
|
||||
}
|
||||
|
||||
Child(Integer id, Parent parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
this.parent.setChild( this );
|
||||
}
|
||||
|
||||
@Id
|
||||
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;
|
||||
}
|
||||
|
||||
@OneToOne(mappedBy = "child")
|
||||
public Parent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(Parent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.onetoone;
|
||||
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.SingularAssociationAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
import org.hibernate.testing.orm.domain.gambit.EntityWithOneToOneJoinTable;
|
||||
import org.hibernate.testing.orm.domain.gambit.SimpleEntity;
|
||||
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.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
EntityWithOneToOneJoinTable.class,
|
||||
SimpleEntity.class
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory
|
||||
public class EntityWithOneToOneJoinTableTest {
|
||||
|
||||
@Test
|
||||
public void basicTest(SessionFactoryScope scope) {
|
||||
final EntityPersister entityWithOneToOneJoinTableDescriptor = scope.getSessionFactory()
|
||||
.getMetamodel()
|
||||
.findEntityDescriptor( EntityWithOneToOneJoinTable.class );
|
||||
final ModelPart other = entityWithOneToOneJoinTableDescriptor.findSubPart( "other" );
|
||||
assertThat( other, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
final SingularAssociationAttributeMapping otherAttributeMapping = (SingularAssociationAttributeMapping) other;
|
||||
|
||||
final ForeignKeyDescriptor foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "Entity_SimpleEntity" ) );
|
||||
assertThat( keyColumn, is( "other_id" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "SIMPLE_ENTITY" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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.metamodel.mapping.onetoone;
|
||||
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.ModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.SingularAssociationAttributeMapping;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
|
||||
import org.hibernate.testing.orm.domain.gambit.EntityWithOneToOneSharingPrimaryKey;
|
||||
import org.hibernate.testing.orm.domain.gambit.SimpleEntity;
|
||||
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.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
EntityWithOneToOneSharingPrimaryKey.class,
|
||||
SimpleEntity.class
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory
|
||||
public class EntityWithOneToOneSharingPrimaryKeyTest {
|
||||
@Test
|
||||
public void basicTest(SessionFactoryScope scope) {
|
||||
final EntityPersister entityDescriptor = scope.getSessionFactory()
|
||||
.getMetamodel()
|
||||
.findEntityDescriptor( EntityWithOneToOneSharingPrimaryKey.class );
|
||||
|
||||
final ModelPart otherAssociation = entityDescriptor.findSubPart( "other" );
|
||||
|
||||
assertThat( otherAssociation, instanceOf( SingularAssociationAttributeMapping.class ) );
|
||||
|
||||
final SingularAssociationAttributeMapping otherAttributeMapping = (SingularAssociationAttributeMapping) otherAssociation;
|
||||
|
||||
ForeignKeyDescriptor foreignKeyDescriptor = otherAttributeMapping.getForeignKeyDescriptor();
|
||||
foreignKeyDescriptor.visitReferringColumns( (keyTable, keyColumn, jdbcMapping) -> {
|
||||
assertThat( keyTable, is( "EntityWithOneToOneSharingPrimaryKey" ) );
|
||||
assertThat( keyColumn, is( "id" ) );
|
||||
} );
|
||||
|
||||
foreignKeyDescriptor.visitTargetColumns( (targetTable, targetColumn, jdbcMapping) -> {
|
||||
assertThat( targetTable, is( "SIMPLE_ENTITY" ) );
|
||||
assertThat( targetColumn, is( "id" ) );
|
||||
} );
|
||||
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ package org.hibernate.orm.test.sql.exec.manytoone;
|
|||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.ManyToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
|
|
|
@ -34,14 +34,14 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
EntityWithBidirectionalOneToOneJoinTableTest.Parent.class,
|
||||
EntityWithBidirectionalOneToOneJoinTableTest.Child.class,
|
||||
EntityWithBidirectionalOneToOneJoinTableTest.Child2.class,
|
||||
EntityWithBidirectionalAssociationsOneOfWhichIsAJoinTableTest.Parent.class,
|
||||
EntityWithBidirectionalAssociationsOneOfWhichIsAJoinTableTest.Child.class,
|
||||
EntityWithBidirectionalAssociationsOneOfWhichIsAJoinTableTest.Child2.class,
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory(generateStatistics = true)
|
||||
public class EntityWithBidirectionalOneToOneJoinTableTest {
|
||||
public class EntityWithBidirectionalAssociationsOneOfWhichIsAJoinTableTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp(SessionFactoryScope scope) {
|
||||
|
@ -232,7 +232,6 @@ public class EntityWithBidirectionalOneToOneJoinTableTest {
|
|||
}
|
||||
|
||||
@OneToOne
|
||||
@JoinTable(name = "PARENT_CHILD2", inverseJoinColumns = @JoinColumn(name = "child_id"), joinColumns = @JoinColumn(name = "parent_id"))
|
||||
public Child2 getChild2() {
|
||||
return child2;
|
||||
}
|
|
@ -12,25 +12,21 @@ import javax.persistence.OneToOne;
|
|||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.boot.MetadataSources;
|
||||
|
||||
import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest;
|
||||
import org.hibernate.testing.orm.junit.FailureExpected;
|
||||
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Chris Cranford
|
||||
*/
|
||||
@Disabled(value = "Composite FK not yet supported")
|
||||
public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunctionalTest {
|
||||
|
||||
@Override
|
||||
|
@ -59,9 +55,9 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
@AfterEach
|
||||
public void tearDown() {
|
||||
inTransaction( session -> {
|
||||
session.createQuery( "delete from Child" ).executeUpdate();
|
||||
session.createQuery( "delete from Child2" ).executeUpdate();
|
||||
session.createQuery( "delete from Parent" ).executeUpdate();
|
||||
session.createQuery( "delete from Child" ).executeUpdate();
|
||||
} );
|
||||
}
|
||||
|
||||
|
@ -70,23 +66,23 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
inTransaction( session -> {
|
||||
final Parent parent = session.get( Parent.class, 1 );
|
||||
Child child = parent.getChild();
|
||||
assertThat( child, CoreMatchers.notNullValue() );
|
||||
assertThat( child, notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child ),
|
||||
"The child eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( child.getName(), CoreMatchers.notNullValue() );
|
||||
assertThat( child.getParent(), CoreMatchers.notNullValue() );
|
||||
assertThat( child.getParent(), CoreMatchers.notNullValue() );
|
||||
assertThat( child.getName(), notNullValue() );
|
||||
assertThat( child.getParent(), notNullValue() );
|
||||
assertThat( child.getParent(), notNullValue() );
|
||||
|
||||
Child2 child2 = parent.getChild2();
|
||||
assertThat( child2, CoreMatchers.notNullValue() );
|
||||
assertThat( child2, notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child2 ),
|
||||
"The child2 eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( child2.getName(), equalTo( "Fab" ) );
|
||||
assertThat( child2.getParent(), CoreMatchers.notNullValue() );
|
||||
assertThat( child2.getParent1(), notNullValue() );
|
||||
|
||||
} );
|
||||
}
|
||||
|
@ -111,33 +107,34 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
inTransaction( session -> {
|
||||
final Parent parent = session.get( Parent.class, 4 );
|
||||
Child child = parent.getChild();
|
||||
assertThat( child, CoreMatchers.notNullValue() );
|
||||
assertThat( child, notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child ),
|
||||
"The child eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( child.getName(), CoreMatchers.notNullValue() );
|
||||
assertThat( child.getParent(), CoreMatchers.notNullValue() );
|
||||
assertThat( child.getName(), notNullValue() );
|
||||
assertThat( child.getParent(), notNullValue() );
|
||||
|
||||
Child2 child2 = parent.getChild2();
|
||||
assertThat( child2, CoreMatchers.notNullValue() );
|
||||
assertThat( child2, notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child2 ),
|
||||
"The child2 eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( child2.getName(), equalTo( "Fab2" ) );
|
||||
assertThat( child2.getParent(), CoreMatchers.notNullValue() );
|
||||
assertThat( child2.getParent().getDescription(), equalTo( "Hibernate OGM" ) );
|
||||
assertThat( child2.getParent1(), notNullValue() );
|
||||
assertThat( child2.getParent1().getDescription(), equalTo( "Hibernate OGM" ) );
|
||||
|
||||
Parent parent2 = child2.getParent2();
|
||||
assertThat( parent2, CoreMatchers.notNullValue() );
|
||||
assertThat( parent2, notNullValue() );
|
||||
assertThat( parent2.getDescription(), equalTo( "Hibernate OGM" ) );
|
||||
assertThat( parent2.getChild(), CoreMatchers.notNullValue() );
|
||||
assertThat( parent2.getChild(), notNullValue() );
|
||||
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected
|
||||
public void testGetParent3() {
|
||||
inTransaction( session -> {
|
||||
|
||||
|
@ -164,28 +161,28 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
assertThat( parent.getDescription(), equalTo( "Hibernate Search" ) );
|
||||
|
||||
Child child = parent.getChild();
|
||||
assertThat( child, CoreMatchers.notNullValue() );
|
||||
assertThat( child, notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child ),
|
||||
"The child eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( child.getName(), CoreMatchers.notNullValue() );
|
||||
assertThat( child.getParent(), CoreMatchers.notNullValue() );
|
||||
assertThat( child.getName(), notNullValue() );
|
||||
assertThat( child.getParent(), notNullValue() );
|
||||
|
||||
Child2 child2 = parent.getChild2();
|
||||
assertThat( child2, CoreMatchers.notNullValue() );
|
||||
assertThat( child2, notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child2 ),
|
||||
"The child2 eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( child2.getName(), equalTo( "Fab2" ) );
|
||||
assertThat( child2.getParent(), CoreMatchers.notNullValue() );
|
||||
assertThat( child2.getParent().getDescription(), equalTo( "Hibernate Search" ) );
|
||||
assertThat( child2.getParent1(), notNullValue() );
|
||||
assertThat( child2.getParent1().getDescription(), equalTo( "Hibernate Search" ) );
|
||||
|
||||
Parent parent2 = child2.getParent2();
|
||||
assertThat( parent2, CoreMatchers.notNullValue() );
|
||||
assertThat( parent2, notNullValue() );
|
||||
assertThat( parent2.getDescription(), equalTo( "Hibernate OGM" ) );
|
||||
assertThat( parent2.getChild(), CoreMatchers.notNullValue() );
|
||||
assertThat( parent2.getChild(), notNullValue() );
|
||||
|
||||
} );
|
||||
}
|
||||
|
@ -199,25 +196,27 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
Hibernate.isInitialized( parent ),
|
||||
"The parent eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( parent, CoreMatchers.notNullValue() );
|
||||
assertThat( parent.getDescription(), CoreMatchers.notNullValue() );
|
||||
assertThat( parent, notNullValue() );
|
||||
assertThat( parent.getDescription(), notNullValue() );
|
||||
Child child1 = parent.getChild();
|
||||
assertThat( child1, CoreMatchers.notNullValue() );
|
||||
assertThat( child1, notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child1 ),
|
||||
"The child eager OneToOne association is not initialized"
|
||||
);
|
||||
Child2 child2 = parent.getChild2();
|
||||
assertThat( child2, CoreMatchers.notNullValue() );
|
||||
assertThat( child2, notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child2 ),
|
||||
"The child2 eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( child2.getParent(), CoreMatchers.notNullValue() );
|
||||
assertThat( child2.getParent1(), notNullValue() );
|
||||
assertThat( child2.getParent2(), notNullValue() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected
|
||||
public void testHqlSelectParent() {
|
||||
inTransaction(
|
||||
session -> {
|
||||
|
@ -228,14 +227,15 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
.setParameter( "id", 1 )
|
||||
.getSingleResult();
|
||||
|
||||
assertThat( parent.getChild(), CoreMatchers.notNullValue() );
|
||||
assertThat( parent.getChild(), notNullValue() );
|
||||
String name = parent.getChild().getName();
|
||||
assertThat( name, CoreMatchers.notNullValue() );
|
||||
assertThat( name, notNullValue() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
@FailureExpected
|
||||
public void testHqlSelectChild() {
|
||||
inTransaction(
|
||||
session -> {
|
||||
|
@ -244,10 +244,10 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
.setParameter( "id", 1 )
|
||||
.getSingleResult();
|
||||
|
||||
assertThat( child.getParent(), CoreMatchers.notNullValue() );
|
||||
assertThat( child.getParent(), notNullValue() );
|
||||
|
||||
String description = child.getParent().getDescription();
|
||||
assertThat( description, CoreMatchers.notNullValue() );
|
||||
assertThat( description, notNullValue() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -257,9 +257,9 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
@Id
|
||||
private Integer id;
|
||||
private String description;
|
||||
@OneToOne(mappedBy = "parent")
|
||||
@OneToOne
|
||||
private Child child;
|
||||
@OneToOne(mappedBy = "parent")
|
||||
@OneToOne(mappedBy = "parent1")
|
||||
private Child2 child2;
|
||||
|
||||
Parent() {
|
||||
|
@ -313,7 +313,8 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
@Id
|
||||
private Integer id;
|
||||
private String name;
|
||||
@OneToOne
|
||||
|
||||
@OneToOne(mappedBy = "child")
|
||||
private Parent parent;
|
||||
|
||||
Child() {
|
||||
|
@ -360,7 +361,7 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
private String name;
|
||||
|
||||
@OneToOne
|
||||
private Parent parent;
|
||||
private Parent parent1;
|
||||
|
||||
@OneToOne
|
||||
private Parent parent2;
|
||||
|
@ -368,10 +369,10 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
Child2() {
|
||||
}
|
||||
|
||||
Child2(Integer id, Parent parent) {
|
||||
Child2(Integer id, Parent parent1) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
this.parent.setChild2( this );
|
||||
this.parent1 = parent1;
|
||||
this.parent1.setChild2( this );
|
||||
}
|
||||
|
||||
|
||||
|
@ -391,12 +392,12 @@ public class EntityWithBidirectionalOneToOneTest extends SessionFactoryBasedFunc
|
|||
this.name = name;
|
||||
}
|
||||
|
||||
public Parent getParent() {
|
||||
return parent;
|
||||
public Parent getParent1() {
|
||||
return parent1;
|
||||
}
|
||||
|
||||
public void setParent(Parent parent) {
|
||||
this.parent = parent;
|
||||
public void setParent1(Parent parent1) {
|
||||
this.parent1 = parent1;
|
||||
}
|
||||
|
||||
public Parent getParent2() {
|
||||
|
|
|
@ -34,13 +34,13 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
|||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
EntityWithOneBidirectionalOneToOneJoinTableTest.Parent.class,
|
||||
EntityWithOneBidirectionalOneToOneJoinTableTest.Child.class,
|
||||
EntityWithOneBidirectionalJoinTableAssociationTest.Parent.class,
|
||||
EntityWithOneBidirectionalJoinTableAssociationTest.Child.class,
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory(generateStatistics = true)
|
||||
public class EntityWithOneBidirectionalOneToOneJoinTableTest {
|
||||
public class EntityWithOneBidirectionalJoinTableAssociationTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp(SessionFactoryScope scope) {
|
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
* 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.sql.exec.onetoone.bidirectional;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
|
||||
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.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
EntityWithTwoBidirectionalAssociationsOneWithJoinTableTest.Parent.class,
|
||||
EntityWithTwoBidirectionalAssociationsOneWithJoinTableTest.Child.class,
|
||||
EntityWithTwoBidirectionalAssociationsOneWithJoinTableTest.Child2.class,
|
||||
}
|
||||
)
|
||||
@ServiceRegistry
|
||||
@SessionFactory(generateStatistics = true)
|
||||
public class EntityWithTwoBidirectionalAssociationsOneWithJoinTableTest {
|
||||
|
||||
@BeforeEach
|
||||
public void setUp(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Parent parent = new Parent( 1, "Hibernate" );
|
||||
Child child = new Child( 2, parent );
|
||||
child.setName( "Acme" );
|
||||
Child2 child2 = new Child2( 3, parent );
|
||||
child2.setName( "Fab" );
|
||||
session.save( parent );
|
||||
session.save( child );
|
||||
session.save( child2 );
|
||||
} );
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery( "delete from Parent" ).executeUpdate();
|
||||
session.createQuery( "delete from Child" ).executeUpdate();
|
||||
session.createQuery( "delete from Child2" ).executeUpdate();
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetParent(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final Parent parent = session.get( Parent.class, 1 );
|
||||
Child child = parent.getChild();
|
||||
assertThat( child, CoreMatchers.notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child ),
|
||||
"The child eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( child.getName(), equalTo( "Acme" ) );
|
||||
assertThat( child.getParent(), CoreMatchers.notNullValue() );
|
||||
|
||||
|
||||
Child2 child2 = parent.getChild2();
|
||||
assertThat( child2, CoreMatchers.notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child2 ),
|
||||
"The child2 eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( child2.getName(), equalTo( "Fab" ) );
|
||||
assertThat( child2.getParent(), CoreMatchers.notNullValue() );
|
||||
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetChild(SessionFactoryScope scope) {
|
||||
scope.inTransaction( session -> {
|
||||
final Child child = session.get( Child.class, 2 );
|
||||
Parent parent = child.getParent();
|
||||
assertThat( parent, CoreMatchers.notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( parent ),
|
||||
"The parent eager OneToOne association is not initialized"
|
||||
);
|
||||
assertThat( parent.getDescription(), CoreMatchers.notNullValue() );
|
||||
|
||||
Child child1 = parent.getChild();
|
||||
assertThat( child1, CoreMatchers.notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child1 ),
|
||||
"The child eager OneToOne association is not initialized"
|
||||
);
|
||||
|
||||
Child2 child2 = parent.getChild2();
|
||||
assertThat( child2, CoreMatchers.notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child2 ),
|
||||
"The child2 eager OneToOne association is not initialized"
|
||||
|
||||
);
|
||||
assertThat( child2.getParent(), CoreMatchers.notNullValue() );
|
||||
} );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHqlSelectChild(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final String queryString = "SELECT c FROM Child c JOIN c.parent d WHERE d.id = :id";
|
||||
final Child child = session.createQuery( queryString, Child.class )
|
||||
.setParameter( "id", 1 )
|
||||
.getSingleResult();
|
||||
|
||||
assertThat( child.getParent(), CoreMatchers.notNullValue() );
|
||||
|
||||
String description = child.getParent().getDescription();
|
||||
assertThat( description, CoreMatchers.notNullValue() );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHqlSelectParent(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final Parent parent = session.createQuery(
|
||||
"SELECT p FROM Parent p JOIN p.child WHERE p.id = :id",
|
||||
Parent.class
|
||||
)
|
||||
.setParameter( "id", 1 )
|
||||
.getSingleResult();
|
||||
|
||||
Child child = parent.getChild();
|
||||
assertThat( child, CoreMatchers.notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child ),
|
||||
"the child have to be initialized"
|
||||
);
|
||||
String name = child.getName();
|
||||
assertThat( name, CoreMatchers.notNullValue() );
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final Parent parent = session.createQuery(
|
||||
"SELECT p FROM Parent p JOIN p.child WHERE p.id = :id",
|
||||
Parent.class
|
||||
)
|
||||
.setParameter( "id", 1 )
|
||||
.getSingleResult();
|
||||
|
||||
Child child = parent.getChild();
|
||||
assertThat( child, CoreMatchers.notNullValue() );
|
||||
assertTrue(
|
||||
Hibernate.isInitialized( child ),
|
||||
"The child have to be initialized"
|
||||
);
|
||||
String name = child.getName();
|
||||
assertThat( name, CoreMatchers.notNullValue() );
|
||||
}
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
@Entity(name = "Parent")
|
||||
@Table(name = "PARENT")
|
||||
public static class Parent {
|
||||
private Integer id;
|
||||
|
||||
private String description;
|
||||
private Child child;
|
||||
private Child2 child2;
|
||||
|
||||
Parent() {
|
||||
}
|
||||
|
||||
public Parent(Integer id, String description) {
|
||||
this.id = id;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@Id
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
@OneToOne
|
||||
@JoinTable(name = "PARENT_CHILD", inverseJoinColumns = @JoinColumn(name = "child_id"), joinColumns = @JoinColumn(name = "parent_id"))
|
||||
public Child getChild() {
|
||||
return child;
|
||||
}
|
||||
|
||||
public void setChild(Child other) {
|
||||
this.child = other;
|
||||
}
|
||||
|
||||
@OneToOne
|
||||
@JoinTable(name = "PARENT_CHILD_2", inverseJoinColumns = @JoinColumn(name = "child_id"), joinColumns = @JoinColumn(name = "parent_id"))
|
||||
public Child2 getChild2() {
|
||||
return child2;
|
||||
}
|
||||
|
||||
public void setChild2(Child2 child2) {
|
||||
this.child2 = child2;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Child")
|
||||
@Table(name = "CHILD")
|
||||
public static class Child {
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
private Parent parent;
|
||||
|
||||
Child() {
|
||||
}
|
||||
|
||||
Child(Integer id, Parent parent) {
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
this.parent.setChild( this );
|
||||
}
|
||||
|
||||
@Id
|
||||
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;
|
||||
}
|
||||
|
||||
@OneToOne(mappedBy = "child")
|
||||
public Parent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(Parent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Child2")
|
||||
@Table(name = "CHILD2")
|
||||
public static class Child2 {
|
||||
private Integer id;
|
||||
|
||||
private String name;
|
||||
private Parent parent;
|
||||
|
||||
Child2() {
|
||||
}
|
||||
|
||||
Child2(Integer id, Parent child) {
|
||||
this.id = id;
|
||||
this.parent = child;
|
||||
this.parent.setChild2( this );
|
||||
}
|
||||
|
||||
@Id
|
||||
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;
|
||||
}
|
||||
|
||||
@OneToOne(mappedBy = "child2")
|
||||
public Parent getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void setParent(Parent parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,11 +10,13 @@ import javax.persistence.Entity;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinTable;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "EntityWithOneToOneJoinTable")
|
||||
public class EntityWithOneToOneJoinTable {
|
||||
private Integer id;
|
||||
|
||||
|
|
|
@ -10,11 +10,13 @@ import javax.persistence.Entity;
|
|||
import javax.persistence.Id;
|
||||
import javax.persistence.OneToOne;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* @author Andrea Boriero
|
||||
*/
|
||||
@Entity
|
||||
@Table(name= "EntityWithOneToOneSharingPrimaryKey")
|
||||
public class EntityWithOneToOneSharingPrimaryKey {
|
||||
private Integer id;
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import java.time.Instant;
|
|||
import java.util.Date;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
|
@ -19,6 +20,7 @@ import org.hibernate.annotations.NaturalId;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "SIMPLE_ENTITY")
|
||||
public class SimpleEntity {
|
||||
private Integer id;
|
||||
|
||||
|
|
Loading…
Reference in New Issue