Fix issue with fetch for hql query
This commit is contained in:
parent
c4673e5a5c
commit
f54105cc51
|
@ -18,17 +18,12 @@ import org.hibernate.sql.ast.tree.from.TableGroup;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class FromClauseAccessImpl implements FromClauseAccess {
|
||||
private List<TableGroup> rootTableGroups;
|
||||
private Map<String, TableGroup> tableGroupBySqlAlias;
|
||||
private Map<NavigablePath, TableGroup> tableGroupByPath;
|
||||
|
||||
public FromClauseAccessImpl() {
|
||||
}
|
||||
|
||||
public List<TableGroup> getRootTableGroups() {
|
||||
return rootTableGroups;
|
||||
}
|
||||
|
||||
public TableGroup getByAlias(String alias) {
|
||||
final TableGroup byAlias = findByAlias( alias );
|
||||
if ( byAlias == null ) {
|
||||
|
@ -45,10 +40,6 @@ public class FromClauseAccessImpl implements FromClauseAccess {
|
|||
}
|
||||
}
|
||||
|
||||
if ( rootTableGroups != null && rootTableGroups.size() == 1 ) {
|
||||
return rootTableGroups.get( 0 );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -61,10 +52,6 @@ public class FromClauseAccessImpl implements FromClauseAccess {
|
|||
}
|
||||
}
|
||||
|
||||
if ( rootTableGroups != null && rootTableGroups.size() == 1 ) {
|
||||
return rootTableGroups.get( 0 );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.hibernate.query.sqm.sql;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -249,6 +250,7 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
private final QueryParameterBindings domainParameterBindings;
|
||||
private final Map<JpaCriteriaParameter<?>,Supplier<SqmJpaCriteriaParameterWrapper<?>>> jpaCriteriaParamResolutions;
|
||||
|
||||
private Map<String,NavigablePath> pluralPersisterElementNavigablePathByFullPath = new HashMap<>();
|
||||
|
||||
private final SqlAliasBaseManager sqlAliasBaseManager = new SqlAliasBaseManager();
|
||||
|
||||
|
@ -673,10 +675,12 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
if ( log.isTraceEnabled() ) {
|
||||
log.tracef( "Visiting explicit joins for `%s`", sqmFrom.getNavigablePath() );
|
||||
}
|
||||
|
||||
sqmFrom.visitSqmJoins(
|
||||
sqmJoin -> consumeExplicitJoin( sqmJoin, lhsTableGroup )
|
||||
sqmJoin -> {
|
||||
consumeExplicitJoin( sqmJoin, lhsTableGroup );
|
||||
}
|
||||
);
|
||||
pluralPersisterElementNavigablePathByFullPath.clear();
|
||||
}
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
|
@ -702,6 +706,8 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
final TableGroupJoin joinedTableGroupJoin;
|
||||
final TableGroup joinedTableGroup;
|
||||
|
||||
final NavigablePath sqmJoinNavigablePath = sqmJoin.getNavigablePath();
|
||||
final NavigablePath parentNavigablePath = sqmJoinNavigablePath.getParent();
|
||||
if ( pathSource instanceof PluralPersistentAttribute ) {
|
||||
final ModelPart pluralPart = lhsTableGroup.getModelPart().findSubPart(
|
||||
sqmJoin.getReferencedPathSource().getPathName(),
|
||||
|
@ -712,7 +718,22 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
|
||||
final PluralAttributeMapping pluralAttributeMapping = (PluralAttributeMapping) pluralPart;
|
||||
|
||||
final NavigablePath elementPath = sqmJoin.getNavigablePath().append( CollectionPart.Nature.ELEMENT.getName() );
|
||||
NavigablePath elementPath;
|
||||
if ( parentNavigablePath == null ) {
|
||||
elementPath = sqmJoinNavigablePath.append( CollectionPart.Nature.ELEMENT.getName() );
|
||||
pluralPersisterElementNavigablePathByFullPath.put( sqmJoin.getNavigablePath().getFullPath(), elementPath );
|
||||
}
|
||||
else {
|
||||
final NavigablePath elementNavigablePath = pluralPersisterElementNavigablePathByFullPath.get( parentNavigablePath.getFullPath() );
|
||||
if ( elementNavigablePath == null ) {
|
||||
elementPath = sqmJoinNavigablePath.append( CollectionPart.Nature.ELEMENT.getName() );
|
||||
pluralPersisterElementNavigablePathByFullPath.put( sqmJoin.getNavigablePath().getFullPath(), elementPath );
|
||||
}
|
||||
else {
|
||||
elementPath = elementNavigablePath.append( pluralAttributeMapping.getPartName() );
|
||||
pluralPersisterElementNavigablePathByFullPath.put( sqmJoin.getNavigablePath().getFullPath(), elementPath.append( CollectionPart.Nature.ELEMENT.getName() ) );
|
||||
}
|
||||
}
|
||||
|
||||
joinedTableGroupJoin = pluralAttributeMapping.createTableGroupJoin(
|
||||
elementPath,
|
||||
|
@ -726,7 +747,7 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
|
||||
lhsTableGroup.addTableGroupJoin( joinedTableGroupJoin );
|
||||
|
||||
fromClauseIndex.register( sqmJoin, joinedTableGroup );
|
||||
fromClauseIndex.register( sqmJoin, joinedTableGroup, elementPath );
|
||||
fromClauseIndex.registerTableGroup( elementPath, joinedTableGroup );
|
||||
}
|
||||
else if ( pathSource instanceof EmbeddedSqmPathSource ) {
|
||||
|
@ -740,10 +761,10 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
final NavigablePath joinedPath;
|
||||
final String explicitAlias = sqmJoin.getExplicitAlias();
|
||||
if ( explicitAlias == null ) {
|
||||
joinedPath = sqmJoin.getNavigablePath();
|
||||
joinedPath = sqmJoinNavigablePath;
|
||||
}
|
||||
else {
|
||||
joinedPath = sqmJoin.getNavigablePath().getParent().append( sqmJoin.getAttribute().getName() );
|
||||
joinedPath = parentNavigablePath.append( sqmJoin.getAttribute().getName() );
|
||||
}
|
||||
joinedTableGroupJoin = ( (TableGroupJoinProducer) joinedPart ).createTableGroupJoin(
|
||||
joinedPath,
|
||||
|
@ -780,10 +801,10 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
final NavigablePath joinedPath;
|
||||
final String explicitAlias = sqmJoin.getExplicitAlias();
|
||||
if ( explicitAlias == null ) {
|
||||
joinedPath = sqmJoin.getNavigablePath();
|
||||
joinedPath = sqmJoinNavigablePath;
|
||||
}
|
||||
else {
|
||||
joinedPath = sqmJoin.getNavigablePath().getParent().append( sqmJoin.getAttribute().getName() );
|
||||
joinedPath = parentNavigablePath.append( sqmJoin.getAttribute().getName() );
|
||||
}
|
||||
|
||||
joinedTableGroupJoin = ( (TableGroupJoinProducer) joinedPart ).createTableGroupJoin(
|
||||
|
@ -806,7 +827,7 @@ public abstract class BaseSqmToSqlAstConverter
|
|||
// add any additional join restrictions
|
||||
if ( sqmJoin.getJoinPredicate() != null ) {
|
||||
if ( sqmJoin.isFetched() ) {
|
||||
QueryLogging.QUERY_MESSAGE_LOGGER.debugf( "Join fetch [" + sqmJoin.getNavigablePath() + "] is restricted" );
|
||||
QueryLogging.QUERY_MESSAGE_LOGGER.debugf( "Join fetch [" + sqmJoinNavigablePath + "] is restricted" );
|
||||
}
|
||||
|
||||
if ( joinedTableGroupJoin == null ) {
|
||||
|
|
|
@ -38,6 +38,10 @@ public class FromClauseIndex extends SimpleFromClauseAccessImpl {
|
|||
}
|
||||
|
||||
public void register(SqmPath<?> sqmPath, TableGroup tableGroup) {
|
||||
register( sqmPath, tableGroup, null );
|
||||
}
|
||||
|
||||
public void register(SqmPath<?> sqmPath, TableGroup tableGroup, NavigablePath identifierForTableGroup) {
|
||||
registerTableGroup( sqmPath.getNavigablePath(), tableGroup );
|
||||
|
||||
if ( sqmPath.getExplicitAlias() != null ) {
|
||||
|
@ -54,17 +58,20 @@ public class FromClauseIndex extends SimpleFromClauseAccessImpl {
|
|||
if ( sqmPath instanceof SqmAttributeJoin ) {
|
||||
final SqmAttributeJoin sqmJoin = (SqmAttributeJoin) sqmPath;
|
||||
if ( sqmJoin.isFetched() ) {
|
||||
registerJoinFetch( sqmJoin );
|
||||
registerJoinFetch( sqmJoin, identifierForTableGroup );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerJoinFetch(SqmAttributeJoin sqmJoin) {
|
||||
private void registerJoinFetch(SqmAttributeJoin sqmJoin, NavigablePath identifierForTableGroup) {
|
||||
if ( fetchesByPath == null ) {
|
||||
fetchesByPath = new HashMap<>();
|
||||
}
|
||||
NavigablePath navigablePath = sqmJoin.getNavigablePath();
|
||||
fetchesByPath.put( navigablePath.getIdentifierForTableGroup(), sqmJoin );
|
||||
if ( identifierForTableGroup != null ) {
|
||||
fetchesByPath.put( identifierForTableGroup.getIdentifierForTableGroup(), sqmJoin );
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isResolved(SqmFrom fromElement) {
|
||||
|
|
|
@ -31,6 +31,12 @@ public class SimpleFromClauseAccessImpl implements FromClauseAccess {
|
|||
|
||||
@Override
|
||||
public void registerTableGroup(NavigablePath navigablePath, TableGroup tableGroup) {
|
||||
SqlTreeCreationLogger.LOGGER.debugf(
|
||||
"Registration of TableGroup [%s] with identifierForTableGroup [%s] for NavigablePath [%s] ",
|
||||
tableGroup,
|
||||
tableGroup.getNavigablePath().getIdentifierForTableGroup(),
|
||||
navigablePath.getIdentifierForTableGroup()
|
||||
);
|
||||
final TableGroup previous = tableGroupMap.put( navigablePath.getIdentifierForTableGroup(), tableGroup );
|
||||
if ( previous != null ) {
|
||||
SqlTreeCreationLogger.LOGGER.debugf(
|
||||
|
|
|
@ -78,13 +78,13 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
return;
|
||||
}
|
||||
|
||||
if ( CollectionLoadingLogger.TRACE_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.tracef(
|
||||
"(%s) Beginning Initializer#resolveInstance for collection : %s",
|
||||
getSimpleConcreteImplName(),
|
||||
LoggingHelper.toLoggableString( getNavigablePath(), collectionKey.getKey() )
|
||||
);
|
||||
}
|
||||
// if ( CollectionLoadingLogger.TRACE_ENABLED ) {
|
||||
// CollectionLoadingLogger.INSTANCE.tracef(
|
||||
// "(%s) Beginning Initializer#resolveInstance for collection : %s",
|
||||
// getSimpleConcreteImplName(),
|
||||
// LoggingHelper.toLoggableString( getNavigablePath(), collectionKey.getKey() )
|
||||
// );
|
||||
// }
|
||||
|
||||
// determine the PersistentCollection instance to use and whether
|
||||
// we (this initializer) is responsible for loading its state
|
||||
|
@ -195,14 +195,14 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
session
|
||||
);
|
||||
|
||||
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.debugf(
|
||||
"(%s) Created new collection wrapper [%s] : %s",
|
||||
getSimpleConcreteImplName(),
|
||||
LoggingHelper.toLoggableString( getNavigablePath(), collectionKey.getKey() ),
|
||||
toLoggableString( collectionInstance )
|
||||
);
|
||||
}
|
||||
// if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
// CollectionLoadingLogger.INSTANCE.debugf(
|
||||
// "(%s) Created new collection wrapper [%s] : %s",
|
||||
// getSimpleConcreteImplName(),
|
||||
// LoggingHelper.toLoggableString( getNavigablePath(), collectionKey.getKey() ),
|
||||
// toLoggableString( collectionInstance )
|
||||
// );
|
||||
// }
|
||||
|
||||
persistenceContext.addUninitializedCollection( collectionDescriptor, collectionInstance, collectionKey.getKey() );
|
||||
|
||||
|
@ -210,14 +210,14 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
}
|
||||
|
||||
if ( responsibility != null ) {
|
||||
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.debugf(
|
||||
"(%s) Responsible for loading collection [%s] : %s",
|
||||
getSimpleConcreteImplName(),
|
||||
LoggingHelper.toLoggableString( getNavigablePath(), collectionKey.getKey() ),
|
||||
toLoggableString( collectionInstance )
|
||||
);
|
||||
}
|
||||
// if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
// CollectionLoadingLogger.INSTANCE.debugf(
|
||||
// "(%s) Responsible for loading collection [%s] : %s",
|
||||
// getSimpleConcreteImplName(),
|
||||
// LoggingHelper.toLoggableString( getNavigablePath(), collectionKey.getKey() ),
|
||||
// toLoggableString( collectionInstance )
|
||||
// );
|
||||
// }
|
||||
|
||||
if ( getParentAccess() != null ) {
|
||||
getParentAccess().registerResolutionListener(
|
||||
|
@ -287,28 +287,12 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
collectionAttributeMapping.getCollectionDescriptor(),
|
||||
keyContainerValue
|
||||
);
|
||||
|
||||
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.debugf(
|
||||
"(%s) Current row collection key : %s",
|
||||
getSimpleConcreteImplName(),
|
||||
LoggingHelper.toLoggableString( getNavigablePath(), this.collectionKey.getKey() )
|
||||
);
|
||||
}
|
||||
}
|
||||
else if ( keyCollectionValue != null ) {
|
||||
this.collectionKey = new CollectionKey(
|
||||
collectionAttributeMapping.getCollectionDescriptor(),
|
||||
keyCollectionValue
|
||||
);
|
||||
|
||||
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.debugf(
|
||||
"(%s) Current row collection key : %s",
|
||||
getSimpleConcreteImplName(),
|
||||
LoggingHelper.toLoggableString( getNavigablePath(), this.collectionKey.getKey() )
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.collectionKey = new CollectionKey(
|
||||
|
@ -351,14 +335,14 @@ public abstract class AbstractImmediateCollectionInitializer extends AbstractCol
|
|||
|
||||
if ( collectionValueKey != null ) {
|
||||
// the row contains an element in the collection...
|
||||
if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
CollectionLoadingLogger.INSTANCE.debugf(
|
||||
"(%s) Reading element from row for collection [%s] -> %s",
|
||||
getSimpleConcreteImplName(),
|
||||
LoggingHelper.toLoggableString( getNavigablePath(), collectionKey.getKey() ),
|
||||
toLoggableString( collectionInstance )
|
||||
);
|
||||
}
|
||||
// if ( CollectionLoadingLogger.DEBUG_ENABLED ) {
|
||||
// CollectionLoadingLogger.INSTANCE.debugf(
|
||||
// "(%s) Reading element from row for collection [%s] -> %s",
|
||||
// getSimpleConcreteImplName(),
|
||||
// LoggingHelper.toLoggableString( getNavigablePath(), collectionKey.getKey() ),
|
||||
// toLoggableString( collectionInstance )
|
||||
// );
|
||||
// }
|
||||
|
||||
responsibility.load(
|
||||
loadingState -> readCollectionRow( collectionKey, loadingState, rowProcessingState )
|
||||
|
|
|
@ -40,6 +40,8 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
private final Object[] resolvedValues;
|
||||
private final boolean createEmptyCompositesEnabled;
|
||||
private Object compositeInstance;
|
||||
private boolean keyResolved;
|
||||
private boolean instanceResolved;
|
||||
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
|
@ -93,6 +95,9 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
|
||||
@Override
|
||||
public void resolveKey(RowProcessingState rowProcessingState) {
|
||||
if(keyResolved){
|
||||
return;
|
||||
}
|
||||
final PropertyAccess parentInjectionPropertyAccess = embeddedModelPartDescriptor.getParentInjectionAttributePropertyAccess();
|
||||
|
||||
final FetchParentAccess fetchParentAccess = getFetchParentAccess();
|
||||
|
@ -113,14 +118,19 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
}
|
||||
);
|
||||
}
|
||||
keyResolved = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resolveInstance(RowProcessingState rowProcessingState) {
|
||||
if ( instanceResolved ) {
|
||||
return;
|
||||
}
|
||||
compositeInstance = embeddedModelPartDescriptor.getEmbeddableTypeDescriptor()
|
||||
.getRepresentationStrategy()
|
||||
.getInstantiator()
|
||||
.instantiate( rowProcessingState.getSession().getFactory() );
|
||||
instanceResolved = true;
|
||||
EmbeddableLoadingLogger.INSTANCE.debugf(
|
||||
"Created composite instance [%s] : %s",
|
||||
navigablePath,
|
||||
|
@ -192,7 +202,8 @@ public abstract class AbstractEmbeddableInitializer extends AbstractFetchParentA
|
|||
@Override
|
||||
public void finishUpRow(RowProcessingState rowProcessingState) {
|
||||
compositeInstance = null;
|
||||
|
||||
keyResolved = true;
|
||||
instanceResolved = false;
|
||||
clearParentResolutionListeners();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ public class EmbeddableAssembler implements DomainResultAssembler {
|
|||
|
||||
@Override
|
||||
public Object assemble(RowProcessingState rowProcessingState, JdbcValuesSourceProcessingOptions options) {
|
||||
initializer.resolveKey( rowProcessingState );
|
||||
initializer.resolveInstance( rowProcessingState );
|
||||
return initializer.getCompositeInstance();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,275 +6,300 @@
|
|||
*/
|
||||
package org.hibernate.test.cid;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.PersistenceException;
|
||||
|
||||
import org.hibernate.Hibernate;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.dialect.Oracle8iDialect;
|
||||
import org.hibernate.dialect.SQLServerDialect;
|
||||
import org.hibernate.exception.SQLGrammarException;
|
||||
|
||||
import org.hibernate.testing.SkipForDialect;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
import org.junit.Test;
|
||||
import org.hibernate.testing.jdbc.SQLStatementInspector;
|
||||
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.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Gavin King
|
||||
*/
|
||||
public class CompositeIdTest extends BaseCoreFunctionalTestCase {
|
||||
@Override
|
||||
public String[] getMappings() {
|
||||
return new String[] { "cid/Customer.hbm.xml", "cid/Order.hbm.xml", "cid/LineItem.hbm.xml", "cid/Product.hbm.xml" };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testQuery() {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
s.createQuery("from LineItem ol where ol.order.id.customerId = 'C111'").list();
|
||||
t.commit();
|
||||
s.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompositeIds() {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
|
||||
Product p = new Product();
|
||||
p.setProductId("A123");
|
||||
p.setDescription("nipple ring");
|
||||
p.setPrice( new BigDecimal(1.0) );
|
||||
p.setNumberAvailable(1004);
|
||||
s.persist(p);
|
||||
|
||||
Product p2 = new Product();
|
||||
p2.setProductId("X525");
|
||||
p2.setDescription("nose stud");
|
||||
p2.setPrice( new BigDecimal(3.0) );
|
||||
p2.setNumberAvailable(105);
|
||||
s.persist(p2);
|
||||
|
||||
Customer c = new Customer();
|
||||
c.setAddress("St Kilda Rd, MEL, 3000");
|
||||
c.setName("Virginia");
|
||||
c.setCustomerId("C111");
|
||||
s.persist(c);
|
||||
|
||||
Order o = new Order(c);
|
||||
o.setOrderDate( Calendar.getInstance() );
|
||||
LineItem li = new LineItem(o, p);
|
||||
li.setQuantity(2);
|
||||
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
o = (Order) s.get( Order.class, new Order.Id("C111", 0) );
|
||||
assertEquals( o.getTotal().intValue(), 2 );
|
||||
o.getCustomer().getName();
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("from Customer c left join fetch c.orders o left join fetch o.lineItems li left join fetch li.product p").list();
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("from Order o left join fetch o.lineItems li left join fetch li.product p").list();
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
Iterator iter = s.createQuery("select o.id, li.id from Order o join o.lineItems li").list().iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
Object[] stuff = (Object[]) iter.next();
|
||||
assertTrue(stuff.length==2);
|
||||
@DomainModel(
|
||||
xmlMappings = {
|
||||
"org/hibernate/test/cid/Customer.hbm.xml",
|
||||
"org/hibernate/test/cid/Order.hbm.xml",
|
||||
"org/hibernate/test/cid/LineItem.hbm.xml",
|
||||
"org/hibernate/test/cid/Product.hbm.xml"
|
||||
}
|
||||
iter = s.createQuery("from Order o join o.lineItems li").list().iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
Object[] stuff = (Object[]) iter.next();
|
||||
assertTrue(stuff.length==2);
|
||||
}
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
c = (Customer) s.get( Customer.class, "C111" );
|
||||
Order o2 = new Order(c);
|
||||
o2.setOrderDate( Calendar.getInstance() );
|
||||
s.flush();
|
||||
LineItem li2 = new LineItem(o2, p2);
|
||||
li2.setQuantity(5);
|
||||
List bigOrders = s.createQuery("from Order o where o.total>10.0").list();
|
||||
assertEquals( bigOrders.size(), 1 );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from LineItem").executeUpdate();
|
||||
s.createQuery("delete from Order").executeUpdate();
|
||||
s.createQuery("delete from Customer").executeUpdate();
|
||||
s.createQuery("delete from Product").executeUpdate();
|
||||
t.commit();
|
||||
s.close();
|
||||
)
|
||||
@SessionFactory(statementInspectorClass = SQLStatementInspector.class)
|
||||
public class CompositeIdTest {
|
||||
|
||||
@AfterEach
|
||||
public void tearDown(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery( "delete from LineItem" ).executeUpdate();
|
||||
session.createQuery( "delete from Order" ).executeUpdate();
|
||||
session.createQuery( "delete from Customer" ).executeUpdate();
|
||||
session.createQuery( "delete from Product" ).executeUpdate();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonLazyFetch() {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
|
||||
Product p = new Product();
|
||||
p.setProductId("A123");
|
||||
p.setDescription("nipple ring");
|
||||
p.setPrice( new BigDecimal(1.0) );
|
||||
p.setNumberAvailable(1004);
|
||||
s.persist(p);
|
||||
|
||||
Product p2 = new Product();
|
||||
p2.setProductId("X525");
|
||||
p2.setDescription("nose stud");
|
||||
p2.setPrice( new BigDecimal(3.0) );
|
||||
p2.setNumberAvailable(105);
|
||||
s.persist(p2);
|
||||
|
||||
Customer c = new Customer();
|
||||
c.setAddress("St Kilda Rd, MEL, 3000");
|
||||
c.setName("Virginia");
|
||||
c.setCustomerId("C111");
|
||||
s.persist(c);
|
||||
|
||||
Order o = new Order(c);
|
||||
o.setOrderDate( Calendar.getInstance() );
|
||||
LineItem li = new LineItem(o, p);
|
||||
li.setQuantity(2);
|
||||
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
o = (Order) s.get( Order.class, new Order.Id("C111", 0) );
|
||||
assertEquals( o.getTotal().intValue(), 2 );
|
||||
o.getCustomer().getName();
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
o = (Order) s.createQuery("from Order o left join fetch o.lineItems li left join fetch li.product p").uniqueResult();
|
||||
assertTrue( Hibernate.isInitialized( o.getLineItems() ) );
|
||||
li = (LineItem) o.getLineItems().iterator().next();
|
||||
assertTrue( Hibernate.isInitialized( li ) );
|
||||
assertTrue( Hibernate.isInitialized( li.getProduct() ) );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
o = (Order) s.createQuery("from Order o").uniqueResult();
|
||||
assertTrue( Hibernate.isInitialized( o.getLineItems() ) );
|
||||
li = (LineItem) o.getLineItems().iterator().next();
|
||||
assertTrue( Hibernate.isInitialized( li ) );
|
||||
assertFalse( Hibernate.isInitialized( li.getProduct() ) );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from LineItem").executeUpdate();
|
||||
s.createQuery("delete from Order").executeUpdate();
|
||||
s.createQuery("delete from Customer").executeUpdate();
|
||||
s.createQuery("delete from Product").executeUpdate();
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
public void testQuery(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session ->
|
||||
session.createQuery( "from LineItem ol where ol.order.id.customerId = 'C111'" ).list()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleCollectionFetch() {
|
||||
Session s = openSession();
|
||||
Transaction t = s.beginTransaction();
|
||||
|
||||
public void testCompositeIds(SessionFactoryScope scope) {
|
||||
Product p = new Product();
|
||||
p.setProductId("A123");
|
||||
p.setDescription("nipple ring");
|
||||
p.setPrice( new BigDecimal(1.0) );
|
||||
p.setNumberAvailable(1004);
|
||||
s.persist(p);
|
||||
|
||||
p.setProductId( "A123" );
|
||||
p.setDescription( "nipple ring" );
|
||||
p.setPrice( new BigDecimal( 1.0 ) );
|
||||
p.setNumberAvailable( 1004 );
|
||||
|
||||
Product p2 = new Product();
|
||||
p2.setProductId("X525");
|
||||
p2.setDescription("nose stud");
|
||||
p2.setPrice( new BigDecimal(3.0) );
|
||||
p2.setNumberAvailable(105);
|
||||
s.persist(p2);
|
||||
|
||||
Customer c = new Customer();
|
||||
c.setAddress("St Kilda Rd, MEL, 3000");
|
||||
c.setName("Virginia");
|
||||
c.setCustomerId("C111");
|
||||
s.persist(c);
|
||||
|
||||
Order o = new Order(c);
|
||||
o.setOrderDate( Calendar.getInstance() );
|
||||
LineItem li = new LineItem(o, p);
|
||||
li.setQuantity(2);
|
||||
LineItem li2 = new LineItem(o, p2);
|
||||
li2.setQuantity(3);
|
||||
p2.setProductId( "X525" );
|
||||
p2.setDescription( "nose stud" );
|
||||
p2.setPrice( new BigDecimal( 3.0 ) );
|
||||
p2.setNumberAvailable( 105 );
|
||||
|
||||
Order o2 = new Order(c);
|
||||
o2.setOrderDate( Calendar.getInstance() );
|
||||
LineItem li3 = new LineItem(o2, p);
|
||||
li3.setQuantity(1);
|
||||
LineItem li4 = new LineItem(o2, p2);
|
||||
li4.setQuantity(1);
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.persist( p );
|
||||
session.persist( p2 );
|
||||
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
c = (Customer) s.createQuery("from Customer c left join fetch c.orders o left join fetch o.lineItems li left join fetch li.product p").uniqueResult();
|
||||
assertTrue( Hibernate.isInitialized( c.getOrders() ) );
|
||||
assertEquals( c.getOrders().size(), 2 );
|
||||
assertTrue( Hibernate.isInitialized( ( (Order) c.getOrders().get(0) ).getLineItems() ) );
|
||||
assertTrue( Hibernate.isInitialized( ( (Order) c.getOrders().get(1) ).getLineItems() ) );
|
||||
assertEquals( ( (Order) c.getOrders().get(0) ).getLineItems().size(), 2 );
|
||||
assertEquals( ( (Order) c.getOrders().get(1) ).getLineItems().size(), 2 );
|
||||
t.commit();
|
||||
s.close();
|
||||
|
||||
s = openSession();
|
||||
t = s.beginTransaction();
|
||||
s.createQuery("delete from LineItem").executeUpdate();
|
||||
s.createQuery("delete from Order").executeUpdate();
|
||||
s.createQuery("delete from Customer").executeUpdate();
|
||||
s.createQuery("delete from Product").executeUpdate();
|
||||
t.commit();
|
||||
s.close();
|
||||
Customer c = new Customer();
|
||||
c.setAddress( "St Kilda Rd, MEL, 3000" );
|
||||
c.setName( "Virginia" );
|
||||
c.setCustomerId( "C111" );
|
||||
session.persist( c );
|
||||
|
||||
Order o = new Order( c );
|
||||
o.setOrderDate( Calendar.getInstance() );
|
||||
LineItem li = new LineItem( o, p );
|
||||
li.setQuantity( 2 );
|
||||
}
|
||||
);
|
||||
|
||||
final SQLStatementInspector statementInspector = (SQLStatementInspector) scope.getStatementInspector();
|
||||
statementInspector.clear();
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Order o = session.get( Order.class, new Order.Id( "C111", 0 ) );
|
||||
statementInspector.assertExecutedCount( 1 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 0,"join", 1 );
|
||||
assertEquals( o.getTotal().intValue(), 2 );
|
||||
o.getCustomer().getName();
|
||||
}
|
||||
);
|
||||
|
||||
statementInspector.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery(
|
||||
"from Customer c left join fetch c.orders o left join fetch o.lineItems li left join fetch li.product p" )
|
||||
.list();
|
||||
statementInspector.assertExecutedCount( 1 );
|
||||
}
|
||||
);
|
||||
|
||||
statementInspector.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
session.createQuery( "from Order o left join fetch o.lineItems li left join fetch li.product p" )
|
||||
.list();
|
||||
statementInspector.assertExecutedCount( 1 );
|
||||
}
|
||||
);
|
||||
|
||||
statementInspector.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Iterator iter = session.createQuery( "select o.id, li.id from Order o join o.lineItems li" )
|
||||
.list()
|
||||
.iterator();
|
||||
statementInspector.assertExecutedCount( 1 );
|
||||
while ( iter.hasNext() ) {
|
||||
Object[] stuff = (Object[]) iter.next();
|
||||
assertTrue( stuff.length == 2 );
|
||||
}
|
||||
statementInspector.assertExecutedCount( 1 );
|
||||
statementInspector.clear();
|
||||
iter = session.createQuery( "from Order o join o.lineItems li" ).list().iterator();
|
||||
statementInspector.assertExecutedCount( 1 );
|
||||
while ( iter.hasNext() ) {
|
||||
Object[] stuff = (Object[]) iter.next();
|
||||
assertTrue( stuff.length == 2 );
|
||||
}
|
||||
statementInspector.assertExecutedCount( 1 );
|
||||
}
|
||||
);
|
||||
|
||||
statementInspector.clear();
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Customer c = session.get( Customer.class, "C111" );
|
||||
statementInspector.assertExecutedCount( 1 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 0,"join", 0 );
|
||||
|
||||
statementInspector.clear();
|
||||
Order o2 = new Order( c );
|
||||
o2.setOrderDate( Calendar.getInstance() );
|
||||
statementInspector.assertExecutedCount( 2 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 0,"join", 0 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 1,"join", 0 );
|
||||
|
||||
statementInspector.clear();
|
||||
session.flush();
|
||||
statementInspector.assertExecutedCount( 4 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 0,"select", 1 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 0,"join", 0 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 1,"insert", 1 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 2,"update", 1 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 3,"update", 1 );
|
||||
|
||||
|
||||
LineItem li2 = new LineItem( o2, p2 );
|
||||
li2.setQuantity( 5 );
|
||||
statementInspector.clear();
|
||||
|
||||
List bigOrders = session.createQuery( "from Order o where o.total>10.0" ).list();
|
||||
statementInspector.assertExecutedCount( 3 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 0,"select", 1 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 0,"join", 0 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 1,"insert", 1 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 2,"select", 2 );
|
||||
statementInspector.assertNumberOfOccurrenceInQuery( 3,"join", 0 );
|
||||
|
||||
assertEquals( bigOrders.size(), 1 );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNonLazyFetch(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Product p = new Product();
|
||||
p.setProductId( "A123" );
|
||||
p.setDescription( "nipple ring" );
|
||||
p.setPrice( new BigDecimal( 1.0 ) );
|
||||
p.setNumberAvailable( 1004 );
|
||||
session.persist( p );
|
||||
|
||||
Product p2 = new Product();
|
||||
p2.setProductId( "X525" );
|
||||
p2.setDescription( "nose stud" );
|
||||
p2.setPrice( new BigDecimal( 3.0 ) );
|
||||
p2.setNumberAvailable( 105 );
|
||||
session.persist( p2 );
|
||||
|
||||
Customer c = new Customer();
|
||||
c.setAddress( "St Kilda Rd, MEL, 3000" );
|
||||
c.setName( "Virginia" );
|
||||
c.setCustomerId( "C111" );
|
||||
session.persist( c );
|
||||
|
||||
Order o = new Order( c );
|
||||
o.setOrderDate( Calendar.getInstance() );
|
||||
LineItem li = new LineItem( o, p );
|
||||
li.setQuantity( 2 );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Order o = session.get( Order.class, new Order.Id( "C111", 0 ) );
|
||||
assertEquals( o.getTotal().intValue(), 2 );
|
||||
o.getCustomer().getName();
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Order o = (Order) session.createQuery(
|
||||
"from Order o left join fetch o.lineItems li left join fetch li.product p" )
|
||||
.uniqueResult();
|
||||
assertTrue( Hibernate.isInitialized( o.getLineItems() ) );
|
||||
LineItem li = (LineItem) o.getLineItems().iterator().next();
|
||||
assertTrue( Hibernate.isInitialized( li ) );
|
||||
assertTrue( Hibernate.isInitialized( li.getProduct() ) );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Order o = (Order) session.createQuery( "from Order o" ).uniqueResult();
|
||||
assertTrue( Hibernate.isInitialized( o.getLineItems() ) );
|
||||
LineItem li = (LineItem) o.getLineItems().iterator().next();
|
||||
assertTrue( Hibernate.isInitialized( li ) );
|
||||
assertFalse( Hibernate.isInitialized( li.getProduct() ) );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleCollectionFetch(SessionFactoryScope scope) {
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Product p = new Product();
|
||||
p.setProductId( "A123" );
|
||||
p.setDescription( "nipple ring" );
|
||||
p.setPrice( new BigDecimal( 1.0 ) );
|
||||
p.setNumberAvailable( 1004 );
|
||||
session.persist( p );
|
||||
|
||||
Product p2 = new Product();
|
||||
p2.setProductId( "X525" );
|
||||
p2.setDescription( "nose stud" );
|
||||
p2.setPrice( new BigDecimal( 3.0 ) );
|
||||
p2.setNumberAvailable( 105 );
|
||||
session.persist( p2 );
|
||||
|
||||
Customer c = new Customer();
|
||||
c.setAddress( "St Kilda Rd, MEL, 3000" );
|
||||
c.setName( "Virginia" );
|
||||
c.setCustomerId( "C111" );
|
||||
session.persist( c );
|
||||
|
||||
Order o = new Order( c );
|
||||
o.setOrderDate( Calendar.getInstance() );
|
||||
LineItem li = new LineItem( o, p );
|
||||
li.setQuantity( 2 );
|
||||
LineItem li2 = new LineItem( o, p2 );
|
||||
li2.setQuantity( 3 );
|
||||
|
||||
Order o2 = new Order( c );
|
||||
o2.setOrderDate( Calendar.getInstance() );
|
||||
LineItem li3 = new LineItem( o2, p );
|
||||
li3.setQuantity( 1 );
|
||||
LineItem li4 = new LineItem( o2, p2 );
|
||||
li4.setQuantity( 1 );
|
||||
}
|
||||
);
|
||||
|
||||
scope.inTransaction(
|
||||
session -> {
|
||||
Customer c = (Customer) session.createQuery(
|
||||
"from Customer c left join fetch c.orders o left join fetch o.lineItems li left join fetch li.product p" )
|
||||
.uniqueResult();
|
||||
assertTrue( Hibernate.isInitialized( c.getOrders() ) );
|
||||
assertEquals( c.getOrders().size(), 2 );
|
||||
assertTrue( Hibernate.isInitialized( ( (Order) c.getOrders().get( 0 ) ).getLineItems() ) );
|
||||
assertTrue( Hibernate.isInitialized( ( (Order) c.getOrders().get( 1 ) ).getLineItems() ) );
|
||||
assertEquals( 2, ( (Order) c.getOrders().get( 0 ) ).getLineItems().size() );
|
||||
assertEquals( 2, ( (Order) c.getOrders().get( 1 ) ).getLineItems().size() );
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue