fixed fk predicate rendering into SQL AST for collections;
basic tests for loading + mapped-fetch strategy
This commit is contained in:
parent
d200fa9545
commit
3cb6e137bf
|
@ -52,7 +52,7 @@ import org.jboss.logging.Logger;
|
|||
public class MetamodelSelectBuilderProcess {
|
||||
private static final Logger log = Logger.getLogger( MetamodelSelectBuilderProcess.class );
|
||||
|
||||
interface SqlAstDescriptor {
|
||||
public interface SqlAstDescriptor {
|
||||
SelectStatement getSqlAst();
|
||||
List<JdbcParameter> getJdbcParameters();
|
||||
}
|
||||
|
|
|
@ -7,7 +7,11 @@
|
|||
package org.hibernate.metamodel.mapping;
|
||||
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.JoinType;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||
import org.hibernate.sql.results.spi.DomainResult;
|
||||
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||
|
||||
|
@ -16,4 +20,11 @@ import org.hibernate.sql.results.spi.DomainResultCreationState;
|
|||
*/
|
||||
public interface ForeignKeyDescriptor {
|
||||
DomainResult createDomainResult(NavigablePath collectionPath, TableGroup tableGroup, DomainResultCreationState creationState);
|
||||
|
||||
Predicate generateJoinPredicate(
|
||||
TableGroup lhs,
|
||||
TableGroup tableGroup,
|
||||
JoinType joinType,
|
||||
SqlExpressionResolver sqlExpressionResolver,
|
||||
SqlAstCreationContext creationContext);
|
||||
}
|
||||
|
|
|
@ -40,7 +40,6 @@ import org.hibernate.mapping.Selectable;
|
|||
import org.hibernate.mapping.ToOne;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.metamodel.CollectionClassification;
|
||||
import org.hibernate.metamodel.mapping.AttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicEntityIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedMapping;
|
||||
import org.hibernate.metamodel.mapping.BasicValuedModelPart;
|
||||
|
@ -647,6 +646,7 @@ public class MappingModelCreationHelper {
|
|||
bootProperty,
|
||||
bootValueMapping,
|
||||
collectionDescriptor,
|
||||
declaringType,
|
||||
dialect,
|
||||
creationProcess
|
||||
);
|
||||
|
@ -849,14 +849,29 @@ public class MappingModelCreationHelper {
|
|||
Property bootProperty,
|
||||
Collection bootValueMapping,
|
||||
CollectionPersister collectionDescriptor,
|
||||
ManagedMappingType declaringType,
|
||||
Dialect dialect,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
final Type keyType = bootValueMapping.getKey().getType();
|
||||
|
||||
final ModelPart fkTarget;
|
||||
final String lhsPropertyName = collectionDescriptor.getCollectionType().getLHSPropertyName();
|
||||
if ( lhsPropertyName == null ) {
|
||||
fkTarget = collectionDescriptor.getOwnerEntityPersister().getIdentifierMapping();
|
||||
}
|
||||
else {
|
||||
fkTarget = declaringType.findAttributeMapping( lhsPropertyName );
|
||||
}
|
||||
|
||||
if ( keyType instanceof BasicType ) {
|
||||
assert bootValueMapping.getKey().getColumnSpan() == 1;
|
||||
assert fkTarget instanceof BasicValuedModelPart;
|
||||
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
|
||||
|
||||
return new SimpleForeignKeyDescriptor(
|
||||
bootValueMapping.getKey().getColumnIterator().next().getText( dialect ),
|
||||
simpleFkTarget.getContainingTableExpression(),
|
||||
simpleFkTarget.getMappedColumnExpression(),
|
||||
(BasicType) keyType
|
||||
);
|
||||
}
|
||||
|
@ -872,31 +887,24 @@ public class MappingModelCreationHelper {
|
|||
EntityPersister referencedEntityDescriptor,
|
||||
Dialect dialect,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
if ( bootValueMapping.isReferenceToPrimaryKey() ) {
|
||||
final EntityIdentifierMapping identifierMapping = referencedEntityDescriptor.getIdentifierMapping();
|
||||
if ( identifierMapping instanceof BasicEntityIdentifierMapping ) {
|
||||
final BasicEntityIdentifierMapping simpleIdMapping = (BasicEntityIdentifierMapping) identifierMapping;
|
||||
|
||||
assert bootValueMapping.getColumnSpan() == 1;
|
||||
return new SimpleForeignKeyDescriptor(
|
||||
bootValueMapping.getColumnIterator().next().getText( dialect ),
|
||||
simpleIdMapping.getJdbcMapping()
|
||||
);
|
||||
}
|
||||
final ModelPart fkTarget;
|
||||
if ( bootValueMapping.isReferenceToPrimaryKey() ) {
|
||||
fkTarget = referencedEntityDescriptor.getIdentifierMapping();
|
||||
}
|
||||
else {
|
||||
final AttributeMapping attributeMapping = referencedEntityDescriptor.findAttributeMapping(
|
||||
bootValueMapping.getReferencedPropertyName()
|
||||
);
|
||||
fkTarget = referencedEntityDescriptor.findSubPart( bootValueMapping.getReferencedPropertyName() );
|
||||
}
|
||||
|
||||
if ( attributeMapping instanceof BasicValuedSingularAttributeMapping ) {
|
||||
final BasicValuedSingularAttributeMapping basicMapping = (BasicValuedSingularAttributeMapping) attributeMapping;
|
||||
assert bootValueMapping.getColumnSpan() == 1;
|
||||
return new SimpleForeignKeyDescriptor(
|
||||
bootValueMapping.getColumnIterator().next().getText( dialect ),
|
||||
basicMapping.getJdbcMapping()
|
||||
);
|
||||
}
|
||||
if ( fkTarget instanceof BasicValuedModelPart ) {
|
||||
final BasicValuedModelPart simpleFkTarget = (BasicValuedModelPart) fkTarget;
|
||||
|
||||
return new SimpleForeignKeyDescriptor(
|
||||
bootValueMapping.getColumnIterator().next().getText( dialect ),
|
||||
simpleFkTarget.getContainingTableExpression(),
|
||||
simpleFkTarget.getMappedColumnExpression(),
|
||||
simpleFkTarget.getJdbcMapping()
|
||||
);
|
||||
}
|
||||
|
||||
throw new NotYetImplementedFor6Exception(
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
|
|||
import org.hibernate.sql.ast.tree.from.TableGroupBuilder;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||
import org.hibernate.sql.ast.tree.from.TableReferenceCollector;
|
||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||
import org.hibernate.sql.results.internal.domain.collection.DelayedCollectionFetch;
|
||||
import org.hibernate.sql.results.internal.domain.collection.EagerCollectionFetch;
|
||||
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||
|
@ -161,9 +162,10 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
|
|||
final TableGroup collectionTableGroup = sqlAstCreationState.getFromClauseAccess().resolveTableGroup(
|
||||
fetchablePath,
|
||||
p -> {
|
||||
final TableGroup lhsTableGroup = sqlAstCreationState.getFromClauseAccess().getTableGroup( fetchParent.getNavigablePath() );
|
||||
final TableGroupJoin tableGroupJoin = createTableGroupJoin(
|
||||
fetchablePath,
|
||||
sqlAstCreationState.getFromClauseAccess().getTableGroup( fetchParent.getNavigablePath() ),
|
||||
lhsTableGroup,
|
||||
null,
|
||||
JoinType.LEFT,
|
||||
lockMode,
|
||||
|
@ -171,6 +173,11 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
|
|||
creationState.getSqlAstCreationState().getSqlExpressionResolver(),
|
||||
creationState.getSqlAstCreationState().getCreationContext()
|
||||
);
|
||||
|
||||
lhsTableGroup.addTableGroupJoin( tableGroupJoin );
|
||||
|
||||
sqlAstCreationState.getFromClauseAccess().registerTableGroup( fetchablePath, tableGroupJoin.getJoinedGroup() );
|
||||
|
||||
return tableGroupJoin.getJoinedGroup();
|
||||
}
|
||||
);
|
||||
|
@ -228,7 +235,23 @@ public class PluralAttributeMappingImpl extends AbstractAttributeMapping impleme
|
|||
creationContext
|
||||
);
|
||||
|
||||
return new TableGroupJoin( navigablePath, joinType, tableGroupBuilder.build() );
|
||||
final TableGroup tableGroup = tableGroupBuilder.build();
|
||||
final TableGroupJoin tableGroupJoin = new TableGroupJoin(
|
||||
navigablePath,
|
||||
joinType,
|
||||
tableGroup,
|
||||
getKeyDescriptor().generateJoinPredicate(
|
||||
lhs,
|
||||
tableGroup,
|
||||
joinType,
|
||||
sqlExpressionResolver,
|
||||
creationContext
|
||||
)
|
||||
);
|
||||
|
||||
lhs.addTableGroupJoin( tableGroupJoin );
|
||||
|
||||
return tableGroupJoin;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,12 +8,18 @@ package org.hibernate.metamodel.mapping.internal;
|
|||
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.query.ComparisonOperator;
|
||||
import org.hibernate.query.NavigablePath;
|
||||
import org.hibernate.sql.ast.JoinType;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationContext;
|
||||
import org.hibernate.sql.ast.spi.SqlAstCreationState;
|
||||
import org.hibernate.sql.ast.spi.SqlExpressionResolver;
|
||||
import org.hibernate.sql.ast.spi.SqlSelection;
|
||||
import org.hibernate.sql.ast.tree.expression.ColumnReference;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableReference;
|
||||
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
||||
import org.hibernate.sql.ast.tree.predicate.Predicate;
|
||||
import org.hibernate.sql.results.internal.domain.basic.BasicResult;
|
||||
import org.hibernate.sql.results.spi.DomainResult;
|
||||
import org.hibernate.sql.results.spi.DomainResultCreationState;
|
||||
|
@ -23,10 +29,18 @@ import org.hibernate.sql.results.spi.DomainResultCreationState;
|
|||
*/
|
||||
public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor {
|
||||
private final String keyColumnExpression;
|
||||
private final String targetColumnContainingTable;
|
||||
private final String targetColumnExpression;
|
||||
private final JdbcMapping jdbcMapping;
|
||||
|
||||
public SimpleForeignKeyDescriptor(String keyColumnExpression, JdbcMapping jdbcMapping) {
|
||||
public SimpleForeignKeyDescriptor(
|
||||
String keyColumnExpression,
|
||||
String targetColumnContainingTable,
|
||||
String targetColumnExpression,
|
||||
JdbcMapping jdbcMapping) {
|
||||
this.keyColumnExpression = keyColumnExpression;
|
||||
this.targetColumnContainingTable = targetColumnContainingTable;
|
||||
this.targetColumnExpression = targetColumnExpression;
|
||||
this.jdbcMapping = jdbcMapping;
|
||||
}
|
||||
|
||||
|
@ -61,4 +75,43 @@ public class SimpleForeignKeyDescriptor implements ForeignKeyDescriptor {
|
|||
jdbcMapping.getJavaTypeDescriptor()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Predicate generateJoinPredicate(
|
||||
TableGroup lhs,
|
||||
TableGroup tableGroup,
|
||||
JoinType joinType,
|
||||
SqlExpressionResolver sqlExpressionResolver,
|
||||
SqlAstCreationContext creationContext) {
|
||||
final TableReference tableReference = lhs.resolveTableReference( targetColumnContainingTable );
|
||||
|
||||
final ColumnReference targetReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey( tableReference, keyColumnExpression ),
|
||||
s -> new ColumnReference(
|
||||
tableReference.getIdentificationVariable(),
|
||||
targetColumnExpression,
|
||||
jdbcMapping,
|
||||
creationContext.getSessionFactory()
|
||||
)
|
||||
);
|
||||
|
||||
final ColumnReference keyReference = (ColumnReference) sqlExpressionResolver.resolveSqlExpression(
|
||||
SqlExpressionResolver.createColumnReferenceKey(
|
||||
tableGroup.getPrimaryTableReference(),
|
||||
keyColumnExpression
|
||||
),
|
||||
s -> new ColumnReference(
|
||||
tableGroup.getPrimaryTableReference().getIdentificationVariable(),
|
||||
keyColumnExpression,
|
||||
jdbcMapping,
|
||||
creationContext.getSessionFactory()
|
||||
)
|
||||
);
|
||||
|
||||
return new ComparisonPredicate(
|
||||
targetReference,
|
||||
ComparisonOperator.EQUAL,
|
||||
keyReference
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6150,7 +6150,6 @@ public abstract class AbstractEntityPersister
|
|||
runtimeAttrDefinition,
|
||||
bootProperty,
|
||||
stateArrayPosition++,
|
||||
this,
|
||||
creationProcess
|
||||
)
|
||||
);
|
||||
|
@ -6311,7 +6310,6 @@ public abstract class AbstractEntityPersister
|
|||
NonIdentifierAttribute tupleAttrDefinition,
|
||||
Property bootProperty,
|
||||
int stateArrayPosition,
|
||||
ManagedMappingType declaringType,
|
||||
MappingModelCreationProcess creationProcess) {
|
||||
|
||||
final String attrName = tupleAttrDefinition.getName();
|
||||
|
@ -6333,7 +6331,7 @@ public abstract class AbstractEntityPersister
|
|||
attrName,
|
||||
stateArrayPosition,
|
||||
bootProperty,
|
||||
declaringType,
|
||||
this,
|
||||
(BasicType) attrType,
|
||||
tableExpression,
|
||||
attrColumnNames[0],
|
||||
|
@ -6347,7 +6345,7 @@ public abstract class AbstractEntityPersister
|
|||
attrName,
|
||||
stateArrayPosition,
|
||||
bootProperty,
|
||||
declaringType,
|
||||
this,
|
||||
(CompositeType) attrType,
|
||||
tableExpression,
|
||||
attrColumnNames,
|
||||
|
@ -6361,7 +6359,7 @@ public abstract class AbstractEntityPersister
|
|||
attrName,
|
||||
stateArrayPosition,
|
||||
bootProperty,
|
||||
declaringType,
|
||||
this,
|
||||
propertyAccess,
|
||||
tupleAttrDefinition.getCascadeStyle(),
|
||||
creationProcess
|
||||
|
|
|
@ -1015,7 +1015,9 @@ public abstract class AbstractSqlAstWalker
|
|||
// }
|
||||
//
|
||||
comparisonPredicate.getLeftHandExpression().accept( this );
|
||||
appendSql( " " );
|
||||
appendSql( comparisonPredicate.getOperator().sqlText() );
|
||||
appendSql( " " );
|
||||
comparisonPredicate.getRightHandExpression().accept( this );
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* 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.loading;
|
||||
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.persistence.CollectionTable;
|
||||
import javax.persistence.ElementCollection;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.FetchType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.JoinColumn;
|
||||
import javax.persistence.OneToMany;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.engine.spi.LoadQueryInfluencers;
|
||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.loader.internal.MetamodelSelectBuilderProcess;
|
||||
import org.hibernate.metamodel.spi.DomainMetamodel;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroup;
|
||||
import org.hibernate.sql.ast.tree.from.TableGroupJoin;
|
||||
import org.hibernate.sql.ast.tree.predicate.ComparisonPredicate;
|
||||
import org.hibernate.sql.ast.tree.select.QuerySpec;
|
||||
import org.hibernate.sql.results.internal.domain.basic.BasicFetch;
|
||||
import org.hibernate.sql.results.internal.domain.collection.DelayedCollectionFetch;
|
||||
import org.hibernate.sql.results.internal.domain.collection.EagerCollectionFetch;
|
||||
import org.hibernate.sql.results.spi.DomainResult;
|
||||
import org.hibernate.sql.results.spi.EntityResult;
|
||||
import org.hibernate.sql.results.spi.Fetch;
|
||||
|
||||
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.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@DomainModel(
|
||||
annotatedClasses = {
|
||||
MappedFetchTests.RootEntity.class,
|
||||
MappedFetchTests.SimpleEntity.class
|
||||
}
|
||||
)
|
||||
@SessionFactory
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class MappedFetchTests {
|
||||
@Test
|
||||
public void baseline(SessionFactoryScope scope) {
|
||||
final SessionFactoryImplementor sessionFactory = scope.getSessionFactory();
|
||||
final DomainMetamodel domainModel = sessionFactory.getDomainModel();
|
||||
final EntityPersister rootEntityDescriptor = domainModel.getEntityDescriptor( RootEntity.class );
|
||||
final MetamodelSelectBuilderProcess.SqlAstDescriptor sqlAstDescriptor = MetamodelSelectBuilderProcess.createSelect(
|
||||
sessionFactory,
|
||||
rootEntityDescriptor,
|
||||
null,
|
||||
rootEntityDescriptor.getIdentifierMapping(),
|
||||
null,
|
||||
1,
|
||||
LoadQueryInfluencers.NONE,
|
||||
LockOptions.NONE
|
||||
);
|
||||
|
||||
assertThat( sqlAstDescriptor.getSqlAst().getDomainResultDescriptors().size(), is( 1 ) );
|
||||
|
||||
final DomainResult domainResult = sqlAstDescriptor.getSqlAst().getDomainResultDescriptors().get( 0 );
|
||||
assertThat( domainResult, instanceOf( EntityResult.class ) );
|
||||
|
||||
final EntityResult entityResult = (EntityResult) domainResult;
|
||||
final List<Fetch> fetches = entityResult.getFetches();
|
||||
|
||||
// name + both lists
|
||||
assertThat( fetches.size(), is( 3 ) );
|
||||
|
||||
// order is alphabetical...
|
||||
|
||||
final Fetch nameFetch = fetches.get( 0 );
|
||||
assertThat( nameFetch.getFetchedMapping().getFetchableName(), is( "name" ) );
|
||||
assertThat( nameFetch, instanceOf( BasicFetch.class ) );
|
||||
|
||||
final Fetch nickNamesFetch = fetches.get( 1 );
|
||||
assertThat( nickNamesFetch.getFetchedMapping().getFetchableName(), is( "nickNames" ) );
|
||||
assertThat( nickNamesFetch, instanceOf( EagerCollectionFetch.class ) );
|
||||
|
||||
final Fetch simpleEntitiesFetch = fetches.get( 2 );
|
||||
assertThat( simpleEntitiesFetch.getFetchedMapping().getFetchableName(), is( "simpleEntities" ) );
|
||||
assertThat( simpleEntitiesFetch, instanceOf( DelayedCollectionFetch.class ) );
|
||||
|
||||
|
||||
final QuerySpec querySpec = sqlAstDescriptor.getSqlAst().getQuerySpec();
|
||||
|
||||
final TableGroup tableGroup = querySpec.getFromClause().getRoots().get( 0 );
|
||||
assertThat( tableGroup.getModelPart(), is( rootEntityDescriptor ) );
|
||||
assertThat( tableGroup.getTableGroupJoins().size(), is( 1 ) );
|
||||
|
||||
final TableGroupJoin collectionJoin = tableGroup.getTableGroupJoins().iterator().next();
|
||||
assertThat( collectionJoin.getJoinedGroup().getModelPart(), is( nickNamesFetch.getFetchedMapping() ) );
|
||||
|
||||
assertThat( collectionJoin.getPredicate(), notNullValue() );
|
||||
assertThat( collectionJoin.getPredicate(), instanceOf( ComparisonPredicate.class ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
public void smokeTest(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final RootEntity first = session.get( RootEntity.class, 1 );
|
||||
assertThat( Hibernate.isInitialized( first ), is( true ) );
|
||||
|
||||
assertThat( Hibernate.isInitialized( first.getNickNames() ), is( true ) );
|
||||
assertThat( first.getNickNames().size(), is( 2 ) );
|
||||
|
||||
assertThat( Hibernate.isInitialized( first.getSimpleEntities() ), is( false ) );
|
||||
|
||||
final RootEntity second = session.get( RootEntity.class, 2 );
|
||||
assertThat( Hibernate.isInitialized( second ), is( true ) );
|
||||
|
||||
assertThat( Hibernate.isInitialized( second.getNickNames() ), is( true ) );
|
||||
assertThat( second.getNickNames().size(), is( 2 ) );
|
||||
|
||||
assertThat( Hibernate.isInitialized( second.getSimpleEntities() ), is( false ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void createTestData(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
final RootEntity root1 = new RootEntity( 1, "first" );
|
||||
root1.addNickName( "1st" );
|
||||
root1.addNickName( "primo" );
|
||||
session.save( root1 );
|
||||
|
||||
final RootEntity root2 = new RootEntity( 2, "second" );
|
||||
root2.addNickName( "2nd" );
|
||||
root2.addNickName( "first loser" );
|
||||
session.save( root2 );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void dropTestData(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> session.doWork(
|
||||
connection -> {
|
||||
try ( Statement statement = connection.createStatement() ) {
|
||||
statement.execute( "delete nick_names" );
|
||||
statement.execute( "delete simple_entity" );
|
||||
statement.execute( "delete root_entity" );
|
||||
}
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Entity( name = "RootEntity" )
|
||||
@Table( name = "root_entity" )
|
||||
public static class RootEntity {
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
private List<String> nickNames;
|
||||
private List<SimpleEntity> simpleEntities;
|
||||
|
||||
public RootEntity() {
|
||||
}
|
||||
|
||||
public RootEntity(Integer id, String name) {
|
||||
this.id = id;
|
||||
this.name = 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;
|
||||
}
|
||||
|
||||
@ElementCollection( fetch = FetchType.EAGER )
|
||||
@CollectionTable( name = "nick_names" )
|
||||
public List<String> getNickNames() {
|
||||
return nickNames;
|
||||
}
|
||||
|
||||
public void setNickNames(List<String> nickNames) {
|
||||
this.nickNames = nickNames;
|
||||
}
|
||||
|
||||
public void addNickName(String name) {
|
||||
if ( nickNames == null ) {
|
||||
nickNames = new ArrayList<>();
|
||||
}
|
||||
nickNames.add( name );
|
||||
}
|
||||
|
||||
@OneToMany( fetch = FetchType.LAZY )
|
||||
@JoinColumn( name = "simple_id" )
|
||||
public List<SimpleEntity> getSimpleEntities() {
|
||||
return simpleEntities;
|
||||
}
|
||||
|
||||
public void setSimpleEntities(List<SimpleEntity> simpleEntities) {
|
||||
this.simpleEntities = simpleEntities;
|
||||
}
|
||||
|
||||
public void addSimpleEntity(SimpleEntity simpleEntity) {
|
||||
if ( simpleEntities == null ) {
|
||||
simpleEntities = new ArrayList<>();
|
||||
}
|
||||
simpleEntities.add( simpleEntity );
|
||||
}
|
||||
}
|
||||
|
||||
@Entity( name = "SimpleEntity" )
|
||||
@Table( name = "simple_entity" )
|
||||
public static class SimpleEntity {
|
||||
private Integer id;
|
||||
private String name;
|
||||
|
||||
public SimpleEntity() {
|
||||
}
|
||||
|
||||
public SimpleEntity(Integer id, String name) {
|
||||
this.id = id;
|
||||
this.name = 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
Reference in New Issue