Fix instantiation of composite property ref

This commit is contained in:
Andrea Boriero 2021-12-20 21:17:45 +01:00 committed by Christian Beikov
parent 99c13e5965
commit dcd4479cf1
33 changed files with 233 additions and 168 deletions

View File

@ -471,7 +471,9 @@ public class CompoundNaturalIdMapping extends AbstractNaturalIdMapping implement
}
@Override
public DomainResultAssembler<Object[]> createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler<Object[]> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
return new AssemblerImpl(
fetches,
navigablePath,

View File

@ -442,7 +442,9 @@ public class DiscriminatedAssociationMapping implements MappingType, FetchOption
}
@Override
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler<T> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
return new AnyResultAssembler<>(
getNavigablePath(),
getReferencedMappingContainer(),

View File

@ -23,6 +23,7 @@ import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.basic.BasicFetch;
import org.hibernate.sql.results.graph.entity.EntityInitializer;
@ -156,7 +157,9 @@ public class EntityResultImpl implements EntityResult {
}
@Override
public DomainResultAssembler<?> createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler<?> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),

View File

@ -11,6 +11,7 @@ import java.util.Map;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
import org.hibernate.sql.results.jdbc.spi.RowProcessingState;
import org.hibernate.type.descriptor.java.JavaType;
@ -42,9 +43,11 @@ public class SqmMapEntryResult<K, V, R extends Map.Entry<K, V>> implements Domai
}
@Override
public DomainResultAssembler<R> createResultAssembler(AssemblerCreationState creationState) {
final DomainResultAssembler<K> keyAssembler = keyResult.createResultAssembler( creationState );
final DomainResultAssembler<V> valueAssembler = valueResult.createResultAssembler( creationState );
public DomainResultAssembler<R> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
final DomainResultAssembler<K> keyAssembler = keyResult.createResultAssembler( null, creationState );
final DomainResultAssembler<V> valueAssembler = valueResult.createResultAssembler( null, creationState );
return new DomainResultAssembler<R>() {
@Override

View File

@ -28,5 +28,7 @@ public interface DomainResult<J> extends DomainResultGraphNode {
/**
* Create an assembler (and any initializers) for this result.
*/
DomainResultAssembler<J> createResultAssembler(AssemblerCreationState creationState);
DomainResultAssembler<J> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState);
}

View File

@ -138,7 +138,9 @@ public class BasicFetch<T> implements Fetch, BasicResultGraphNode<T> {
}
@Override
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler<T> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
return assembler;
}

View File

@ -12,6 +12,7 @@ import org.hibernate.query.NavigablePath;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.type.descriptor.java.JavaType;
/**
@ -90,7 +91,9 @@ public class BasicResult<T> implements DomainResult<T>, BasicResultGraphNode<T>
}
@Override
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler<T> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
return assembler;
}
}

View File

@ -21,6 +21,7 @@ import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParent;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
@ -85,12 +86,14 @@ public class CollectionDomainResult implements DomainResult, CollectionResultGra
}
@Override
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
final CollectionInitializer initializer = (CollectionInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),
() -> {
final DomainResultAssembler fkAssembler = fkResult.createResultAssembler( creationState );
final DomainResultAssembler fkAssembler = fkResult.createResultAssembler( null, creationState );
return initializerProducer.produceInitializer(
loadingPath,

View File

@ -13,6 +13,7 @@ import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.collection.CollectionInitializer;
import org.hibernate.sql.results.graph.embeddable.internal.EmbeddableForeignKeyResultImpl;
/**
* @author Steve Ebersole
@ -30,7 +31,10 @@ public class DelayedCollectionAssembler extends AbstractCollectionAssembler {
fetchPath,
fetchedMapping,
() -> {
final DomainResultAssembler<?> collectionKeyAssembler = collectionKeyResult.createResultAssembler( creationState );
final DomainResultAssembler<?> collectionKeyAssembler = collectionKeyResult.createResultAssembler(
parentAccess,
creationState
);
return new DelayedCollectionInitializer(
fetchPath,
fetchedMapping,

View File

@ -130,8 +130,8 @@ public class EagerCollectionFetch extends CollectionFetch implements FetchParent
getNavigablePath(),
getReferencedModePart(),
() -> {
final DomainResultAssembler<?> collectionKeyAssembler = collectionKeyResult.createResultAssembler( creationState );
final DomainResultAssembler<?> collectionValueKeyAssembler = collectionValueKeyResult.createResultAssembler( creationState );
final DomainResultAssembler<?> collectionKeyAssembler = collectionKeyResult.createResultAssembler( null, creationState );
final DomainResultAssembler<?> collectionValueKeyAssembler = collectionValueKeyResult.createResultAssembler( null, creationState );
return initializerProducer.produceInitializer(
getNavigablePath(),

View File

@ -49,7 +49,7 @@ public class SelectEagerCollectionFetch extends CollectionFetch {
getNavigablePath(),
getFetchedMapping(),
parentAccess,
collectionKeyDomainResult == null ? null : collectionKeyDomainResult.createResultAssembler( creationState ),
collectionKeyDomainResult == null ? null : collectionKeyDomainResult.createResultAssembler( null, creationState ),
creationState
);
}

View File

@ -18,6 +18,7 @@ import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.embeddable.EmbeddableInitializer;
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
@ -81,11 +82,13 @@ public class EmbeddableForeignKeyResultImpl<T>
}
@Override
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler<T> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),
() -> new EmbeddableResultInitializer(this, creationState )
() -> new EmbeddableResultInitializer( this, parentAccess, creationState )
);
//noinspection unchecked

View File

@ -21,6 +21,7 @@ import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.Fetch;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.embeddable.EmbeddableInitializer;
import org.hibernate.sql.results.graph.embeddable.EmbeddableResult;
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
@ -109,12 +110,15 @@ public class EmbeddableResultImpl<T> extends AbstractFetchParent implements Embe
}
@Override
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler<T> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
final EmbeddableInitializer initializer = (EmbeddableInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),
() -> new EmbeddableResultInitializer(
this,
parentAccess,
creationState
)
);

View File

@ -7,6 +7,7 @@
package org.hibernate.sql.results.graph.embeddable.internal;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.embeddable.AbstractEmbeddableInitializer;
import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
@ -16,8 +17,9 @@ import org.hibernate.sql.results.graph.embeddable.EmbeddableResultGraphNode;
public class EmbeddableResultInitializer extends AbstractEmbeddableInitializer {
public EmbeddableResultInitializer(
EmbeddableResultGraphNode resultDescriptor,
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
super( resultDescriptor, null, creationState );
super( resultDescriptor, parentAccess, creationState );
}
@Override

View File

@ -153,6 +153,7 @@ public abstract class AbstractEntityInitializer extends AbstractFetchParentAcces
if ( rowIdResult != null ) {
this.rowIdAssembler = rowIdResult.createResultAssembler(
this,
creationState
);
}

View File

@ -59,7 +59,7 @@ public class EntityDelayedFetchImpl extends AbstractNonJoinedEntityFetch {
navigablePath,
(ToOneAttributeMapping) getEntityValuedModelPart(),
selectByUniqueKey,
keyResult.createResultAssembler( creationState )
keyResult.createResultAssembler( parentAccess, creationState )
)
);

View File

@ -15,6 +15,7 @@ import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.entity.EntityInitializer;
import org.hibernate.type.descriptor.java.JavaType;
@ -59,7 +60,9 @@ public class EntityDelayedResultImpl implements DomainResult {
}
@Override
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),
entityValuedModelPart,
@ -68,7 +71,7 @@ public class EntityDelayedResultImpl implements DomainResult {
getNavigablePath(),
(ToOneAttributeMapping) entityValuedModelPart,
false,
identifierResult.createResultAssembler( creationState )
identifierResult.createResultAssembler( parentAccess, creationState )
)
);

View File

@ -65,7 +65,7 @@ public class EntityFetchSelectImpl extends AbstractNonJoinedEntityFetch {
fetchedAttribute,
getNavigablePath(),
entityPersister,
result.createResultAssembler( creationState )
result.createResultAssembler( parentAccess, creationState )
);
}
if ( entityPersister.isBatchLoadable() ) {
@ -74,7 +74,7 @@ public class EntityFetchSelectImpl extends AbstractNonJoinedEntityFetch {
fetchedAttribute,
getNavigablePath(),
entityPersister,
result.createResultAssembler( creationState )
result.createResultAssembler( parentAccess, creationState )
);
}
else {
@ -83,7 +83,7 @@ public class EntityFetchSelectImpl extends AbstractNonJoinedEntityFetch {
fetchedAttribute,
getNavigablePath(),
entityPersister,
result.createResultAssembler( creationState )
result.createResultAssembler( parentAccess, creationState )
);
}
}

View File

@ -16,6 +16,7 @@ import org.hibernate.sql.ast.tree.from.TableGroupProducer;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.Fetchable;
import org.hibernate.sql.results.graph.FetchableContainer;
import org.hibernate.sql.results.graph.entity.AbstractEntityResultGraphNode;
@ -86,7 +87,9 @@ public class EntityResultImpl extends AbstractEntityResultGraphNode implements E
}
@Override
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),

View File

@ -12,6 +12,7 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.DomainResultCreationState;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.entity.EntityInitializer;
/**
@ -28,7 +29,9 @@ public class EntityResultJoinedSubclassImpl extends EntityResultImpl {
}
@Override
public DomainResultAssembler createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),
getReferencedModePart(),

View File

@ -8,6 +8,7 @@ package org.hibernate.sql.results.graph.instantiation.internal;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.type.descriptor.java.JavaType;
/**
@ -37,9 +38,11 @@ public class ArgumentDomainResult<A> implements DomainResult<A> {
}
@Override
public ArgumentReader<A> createResultAssembler(AssemblerCreationState creationState) {
public ArgumentReader<A> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
return new ArgumentReader<>(
realDomainResult.createResultAssembler( creationState ),
realDomainResult.createResultAssembler( parentAccess, creationState ),
getResultVariable()
);
}

View File

@ -19,6 +19,7 @@ import org.hibernate.query.DynamicInstantiationNature;
import org.hibernate.query.sqm.tree.expression.Compatibility;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.instantiation.DynamicInstantiationResult;
import org.hibernate.type.descriptor.java.JavaType;
@ -71,7 +72,9 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
}
@Override
public DomainResultAssembler<R> createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler<R> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
boolean areAllArgumentsAliased = true;
boolean areAnyArgumentsAliased = false;
final Set<String> aliases = new HashSet<>();
@ -95,7 +98,7 @@ public class DynamicInstantiationResultImpl<R> implements DynamicInstantiationRe
}
argumentReaders.add(
argumentResult.createResultAssembler( creationState )
argumentResult.createResultAssembler( parentAccess, creationState )
);
}
}

View File

@ -11,6 +11,7 @@ import org.hibernate.query.NavigablePath;
import org.hibernate.sql.results.graph.AssemblerCreationState;
import org.hibernate.sql.results.graph.DomainResult;
import org.hibernate.sql.results.graph.DomainResultAssembler;
import org.hibernate.sql.results.graph.FetchParentAccess;
import org.hibernate.sql.results.graph.basic.BasicResultGraphNode;
import org.hibernate.type.descriptor.java.JavaType;
@ -69,7 +70,9 @@ public class TupleResult<T> implements DomainResult<T>, BasicResultGraphNode<T>
}
@Override
public DomainResultAssembler<T> createResultAssembler(AssemblerCreationState creationState) {
public DomainResultAssembler<T> createResultAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
return assembler;
}
}

View File

@ -105,7 +105,7 @@ public class CircularBiDirectionalFetchImpl implements BiDirectionalFetch, Assoc
fetchable,
getReferencedPath(),
fetchable.getJavaTypeDescriptor(),
keyDomainResult == null ? null : keyDomainResult.createResultAssembler( creationState )
keyDomainResult == null ? null : keyDomainResult.createResultAssembler( parentAccess, creationState )
);
}

View File

@ -102,7 +102,7 @@ public class CircularFetchImpl implements BiDirectionalFetch, Association {
public DomainResultAssembler createAssembler(
FetchParentAccess parentAccess,
AssemblerCreationState creationState) {
final DomainResultAssembler resultAssembler = keyResult.createResultAssembler( creationState );
final DomainResultAssembler resultAssembler = keyResult.createResultAssembler( parentAccess, creationState );
final EntityInitializer initializer = (EntityInitializer) creationState.resolveInitializer(
getNavigablePath(),

View File

@ -50,7 +50,7 @@ public class StandardJdbcValuesMapping implements JdbcValuesMapping {
//noinspection ForLoopReplaceableByForEach
for ( int i = 0; i < domainResults.size(); i++ ) {
final DomainResultAssembler<?> resultAssembler = domainResults.get( i ).createResultAssembler( creationState );
final DomainResultAssembler<?> resultAssembler = domainResults.get( i ).createResultAssembler( null, creationState );
assemblers.add( resultAssembler );
}

View File

@ -6,7 +6,7 @@
*/
//$Id: Account.java 4592 2004-09-26 00:39:43Z oneovthafew $
package org.hibernate.test.cuk;
package org.hibernate.orm.test.cuk;
import java.io.Serializable;
/**

View File

@ -6,7 +6,7 @@
*/
//$Id: Address.java 4592 2004-09-26 00:39:43Z oneovthafew $
package org.hibernate.test.cuk;
package org.hibernate.orm.test.cuk;
import java.io.Serializable;
/**

View File

@ -0,0 +1,141 @@
/*
* 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.cuk;
import java.util.List;
import java.util.Set;
import org.hibernate.Hibernate;
import org.hibernate.cfg.Environment;
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.hibernate.testing.orm.junit.Setting;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Gavin King
*/
@DomainModel(
xmlMappings = "org/hibernate/orm/test/cuk/Person.hbm.xml"
)
@SessionFactory
@ServiceRegistry(
settings = @Setting(name = Environment.DEFAULT_BATCH_FETCH_SIZE, value = "1")
)
public class CompositePropertyRefTest {
@Test
@SuppressWarnings({ "unchecked", "UnusedAssignment" })
public void testOneToOnePropertyRef(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
Person p = new Person();
p.setName( "Steve" );
p.setUserId( "steve" );
Address a = new Address();
a.setAddress( "Texas" );
a.setCountry( "USA" );
p.setAddress( a );
a.setPerson( p );
session.save( p );
Person p2 = new Person();
p2.setName( "Max" );
p2.setUserId( "max" );
session.save( p2 );
Account act = new Account();
act.setType( 'c' );
act.setUser( p2 );
p2.getAccounts().add( act );
session.save( act );
session.flush();
session.clear();
p = session.get( Person.class, p.getId() ); //get address reference by outer join
p2 = session.get( Person.class, p2.getId() ); //get null address reference by outer join
assertNull( p2.getAddress() );
assertNotNull( p.getAddress() );
List l = session.createQuery( "from Person" ).list(); //pull address references for cache
assertEquals( 2, l.size() );
assertTrue( l.contains( p ) && l.contains( p2 ) );
session.clear();
l = session.createQuery( "from Person p order by p.name" )
.list(); //get address references by sequential selects
assertEquals( 2, l.size() );
assertNull( ( (Person) l.get( 0 ) ).getAddress() );
assertNotNull( ( (Person) l.get( 1 ) ).getAddress() );
session.clear();
l = session.createQuery( "from Person p left join fetch p.address a order by a.country" )
.list(); //get em by outer join
assertEquals( 2, l.size() );
if ( ( (Person) l.get( 0 ) ).getName().equals( "Max" ) ) {
assertNull( ( (Person) l.get( 0 ) ).getAddress() );
assertNotNull( ( (Person) l.get( 1 ) ).getAddress() );
}
else {
assertNull( ( (Person) l.get( 1 ) ).getAddress() );
assertNotNull( ( (Person) l.get( 0 ) ).getAddress() );
}
session.clear();
l = session.createQuery( "from Person p left join p.accounts" ).list();
for ( int i = 0; i < 2; i++ ) {
Person px = (Person) l.get( i );
Set accounts = px.getAccounts();
assertFalse( Hibernate.isInitialized( accounts ) );
// assertTrue( px.getAccounts().size()>0 || row[1]==null );
}
session.clear();
l = session.createQuery( "from Person p left join fetch p.accounts a order by p.name" ).list();
Person p0 = (Person) l.get( 0 );
assertTrue( Hibernate.isInitialized( p0.getAccounts() ) );
assertEquals( 1, p0.getAccounts().size() );
assertSame( ( (Account) p0.getAccounts().iterator().next() ).getUser(), p0 );
Person p1 = (Person) l.get( 1 );
assertTrue( Hibernate.isInitialized( p1.getAccounts() ) );
assertEquals( 0, p1.getAccounts().size() );
session.clear();
l = session.createQuery( "from Account a join fetch a.user" ).list();
session.clear();
l = session.createQuery( "from Person p left join fetch p.address" ).list();
session.clear();
}
);
}
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
session.createQuery( "delete Address" ).executeUpdate();
session.createQuery( "delete Account" ).executeUpdate();
session.createQuery( "delete Person" ).executeUpdate();
}
);
}
}

View File

@ -23,7 +23,7 @@
-->
<hibernate-mapping package="org.hibernate.test.cuk">
<hibernate-mapping package="org.hibernate.orm.test.cuk">
<class name="Person">
<id name="id">

View File

@ -6,7 +6,7 @@
*/
//$Id: Person.java 4592 2004-09-26 00:39:43Z oneovthafew $
package org.hibernate.test.cuk;
package org.hibernate.orm.test.cuk;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

View File

@ -208,7 +208,7 @@ public class SmokeTests {
// ScalarDomainResultImpl creates and caches the assembler at its creation.
// this just gets access to that cached one
final DomainResultAssembler resultAssembler = domainResult.createResultAssembler( null );
final DomainResultAssembler resultAssembler = domainResult.createResultAssembler( null, null );
assertThat( resultAssembler, instanceOf( BasicResultAssembler.class ) );
final BasicValueConverter valueConverter = ( (BasicResultAssembler) resultAssembler ).getValueConverter();

View File

@ -1,128 +0,0 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.cuk;
import java.util.List;
import java.util.Set;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
/**
* @author Gavin King
*/
public class CompositePropertyRefTest extends BaseCoreFunctionalTestCase {
public String[] getMappings() {
return new String[] { "cuk/Person.hbm.xml" };
}
public void configure(Configuration cfg) {
cfg.setProperty(Environment.DEFAULT_BATCH_FETCH_SIZE, "1");
}
@Test
@SuppressWarnings( {"unchecked", "UnusedAssignment"})
public void testOneToOnePropertyRef() {
Session s = openSession();
Transaction t = s.beginTransaction();
Person p = new Person();
p.setName("Steve");
p.setUserId("steve");
Address a = new Address();
a.setAddress("Texas");
a.setCountry("USA");
p.setAddress(a);
a.setPerson(p);
s.save(p);
Person p2 = new Person();
p2.setName("Max");
p2.setUserId("max");
s.save(p2);
Account act = new Account();
act.setType('c');
act.setUser(p2);
p2.getAccounts().add(act);
s.save(act);
s.flush();
s.clear();
p = s.get( Person.class, p.getId() ); //get address reference by outer join
p2 = s.get( Person.class, p2.getId() ); //get null address reference by outer join
assertNull( p2.getAddress() );
assertNotNull( p.getAddress() );
List l = s.createQuery("from Person").list(); //pull address references for cache
assertEquals( l.size(), 2 );
assertTrue( l.contains(p) && l.contains(p2) );
s.clear();
l = s.createQuery("from Person p order by p.name").list(); //get address references by sequential selects
assertEquals( l.size(), 2 );
assertNull( ( (Person) l.get(0) ).getAddress() );
assertNotNull( ( (Person) l.get(1) ).getAddress() );
s.clear();
l = s.createQuery("from Person p left join fetch p.address a order by a.country").list(); //get em by outer join
assertEquals( l.size(), 2 );
if ( ( (Person) l.get(0) ).getName().equals("Max") ) {
assertNull( ( (Person) l.get(0) ).getAddress() );
assertNotNull( ( (Person) l.get(1) ).getAddress() );
}
else {
assertNull( ( (Person) l.get(1) ).getAddress() );
assertNotNull( ( (Person) l.get(0) ).getAddress() );
}
s.clear();
l = s.createQuery("from Person p left join p.accounts").list();
for ( int i=0; i<2; i++ ) {
Object[] row = (Object[]) l.get(i);
Person px = (Person) row[0];
Set accounts = px.getAccounts();
assertFalse( Hibernate.isInitialized(accounts) );
assertTrue( px.getAccounts().size()>0 || row[1]==null );
}
s.clear();
l = s.createQuery("from Person p left join fetch p.accounts a order by p.name").list();
Person p0 = (Person) l.get(0);
assertTrue( Hibernate.isInitialized( p0.getAccounts() ) );
assertEquals( p0.getAccounts().size(), 1 );
assertSame( ( (Account) p0.getAccounts().iterator().next() ).getUser(), p0 );
Person p1 = (Person) l.get(1);
assertTrue( Hibernate.isInitialized( p1.getAccounts() ) );
assertEquals( p1.getAccounts().size(), 0 );
s.clear();
l = s.createQuery("from Account a join fetch a.user").list();
s.clear();
l = s.createQuery("from Person p left join fetch p.address").list();
s.clear();
s.createQuery( "delete Address" ).executeUpdate();
s.createQuery( "delete Account" ).executeUpdate();
s.createQuery( "delete Person" ).executeUpdate();
t.commit();
s.close();
}
}