use of org.hibernate.loader.MultipleBagFetchException in project hibernate-orm by hibernate.
the class MultipleBagFetchTest method testEntityWithMultipleJoinFetchedBags.
@Test
public void testEntityWithMultipleJoinFetchedBags() {
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().build();
Metadata metadata = new MetadataSources(standardRegistry).addAnnotatedClass(Post.class).addAnnotatedClass(PostComment.class).addAnnotatedClass(Tag.class).getMetadataBuilder().build();
try {
metadata.buildSessionFactory();
fail("MultipleBagFetchException should have been thrown.");
} catch (MultipleBagFetchException expected) {
}
}
use of org.hibernate.loader.MultipleBagFetchException in project vladmihalcea.wordpress.com by vladmihalcea.
the class HibernateBagMultiLevelFetchTest method test.
@Test
public void test() {
final Long forestId = transactionTemplate.execute(new TransactionCallback<Long>() {
@Override
public Long doInTransaction(TransactionStatus transactionStatus) {
BagForest forest = new BagForest();
BagTree tree1 = new BagTree();
tree1.setIndex(0);
BagBranch branch11 = new BagBranch();
branch11.setIndex(0);
BagLeaf leaf111 = new BagLeaf();
leaf111.setIndex(0);
BagLeaf leaf112 = new BagLeaf();
leaf111.setIndex(1);
BagLeaf leaf113 = new BagLeaf();
leaf111.setIndex(2);
BagLeaf leaf114 = new BagLeaf();
leaf111.setIndex(3);
branch11.addLeaf(leaf111);
branch11.addLeaf(leaf112);
branch11.addLeaf(leaf113);
branch11.addLeaf(leaf114);
BagBranch branch12 = new BagBranch();
branch12.setIndex(1);
BagLeaf leaf121 = new BagLeaf();
leaf121.setIndex(1);
BagLeaf leaf122 = new BagLeaf();
leaf122.setIndex(2);
BagLeaf leaf123 = new BagLeaf();
leaf123.setIndex(3);
BagLeaf leaf124 = new BagLeaf();
leaf124.setIndex(4);
branch12.addLeaf(leaf121);
branch12.addLeaf(leaf122);
branch12.addLeaf(leaf123);
branch12.addLeaf(leaf124);
tree1.addBranch(branch11);
tree1.addBranch(branch12);
BagTree tree2 = new BagTree();
tree2.setIndex(1);
BagBranch branch21 = new BagBranch();
branch21.setIndex(0);
BagLeaf leaf211 = new BagLeaf();
leaf211.setIndex(0);
BagLeaf leaf212 = new BagLeaf();
leaf111.setIndex(1);
BagLeaf leaf213 = new BagLeaf();
leaf111.setIndex(2);
BagLeaf leaf214 = new BagLeaf();
leaf111.setIndex(3);
branch21.addLeaf(leaf211);
branch21.addLeaf(leaf212);
branch21.addLeaf(leaf213);
branch21.addLeaf(leaf214);
BagBranch branch22 = new BagBranch();
branch22.setIndex(2);
BagLeaf leaf221 = new BagLeaf();
leaf121.setIndex(0);
BagLeaf leaf222 = new BagLeaf();
leaf121.setIndex(1);
BagLeaf leaf223 = new BagLeaf();
leaf121.setIndex(2);
branch22.addLeaf(leaf221);
branch22.addLeaf(leaf222);
branch22.addLeaf(leaf223);
tree2.addBranch(branch21);
tree2.addBranch(branch22);
forest.addTree(tree1);
forest.addTree(tree2);
entityManager.persist(forest);
entityManager.flush();
return forest.getId();
}
});
BagForest forest = transactionTemplate.execute(new TransactionCallback<BagForest>() {
@Override
public BagForest doInTransaction(TransactionStatus transactionStatus) {
return entityManager.find(BagForest.class, forestId);
}
});
try {
navigateForest(forest);
fail("Should have thrown LazyInitializationException!");
} catch (LazyInitializationException expected) {
}
forest = transactionTemplate.execute(new TransactionCallback<BagForest>() {
@Override
public BagForest doInTransaction(TransactionStatus transactionStatus) {
BagForest forest = entityManager.find(BagForest.class, forestId);
navigateForest(forest);
return forest;
}
});
try {
forest = transactionTemplate.execute(new TransactionCallback<BagForest>() {
@Override
public BagForest doInTransaction(TransactionStatus transactionStatus) {
BagForest forest = entityManager.createQuery("select f " + "from BagForest f " + "join fetch f.trees t " + "join fetch t.branches b " + "join fetch b.leaves l ", BagForest.class).getSingleResult();
return forest;
}
});
fail("Should have thrown MultipleBagFetchException!");
} catch (PersistenceException expected) {
assertEquals(MultipleBagFetchException.class, expected.getCause().getClass());
}
List<BagLeaf> leaves = transactionTemplate.execute(new TransactionCallback<List<BagLeaf>>() {
@Override
public List<BagLeaf> doInTransaction(TransactionStatus transactionStatus) {
List<BagLeaf> leaves = entityManager.createQuery("select l " + "from BagLeaf l " + "inner join fetch l.branch b " + "inner join fetch b.tree t " + "inner join fetch t.forest f " + "where f.id = :forestId", BagLeaf.class).setParameter("forestId", forestId).getResultList();
return leaves;
}
});
forest = reconstructForest(leaves, forestId);
navigateForest(forest);
final BagBranch firstBranch = forest.getTrees().get(0).getBranches().get(0);
firstBranch.getLeaves().clear();
final BagForest toMergeForest = forest;
transactionTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus status) {
BagForest savedForest = entityManager.merge(toMergeForest);
if (!firstBranch.getLeaves().equals(savedForest.getTrees().get(0).getBranches().get(0).getLeaves())) {
LOG.error("Unsafe reusing the bag, changes haven't propagated!");
}
entityManager.flush();
return null;
}
});
transactionTemplate.execute(new TransactionCallback<Void>() {
@Override
public Void doInTransaction(TransactionStatus status) {
BagForest savedForest = entityManager.find(BagForest.class, forestId);
if (!firstBranch.getLeaves().equals(savedForest.getTrees().get(0).getBranches().get(0).getLeaves())) {
LOG.error("Unsafe reusing the bag, changes haven't propagated!");
}
return null;
}
});
}
use of org.hibernate.loader.MultipleBagFetchException in project hibernate-orm by hibernate.
the class ExceptionConverterImpl method convert.
@Override
public RuntimeException convert(HibernateException e, LockOptions lockOptions) {
Throwable cause = e;
if (cause instanceof StaleStateException) {
final PersistenceException converted = wrapStaleStateException((StaleStateException) cause);
handlePersistenceException(converted);
return converted;
} else if (cause instanceof LockingStrategyException) {
final PersistenceException converted = wrapLockException((HibernateException) cause, lockOptions);
handlePersistenceException(converted);
return converted;
} else if (cause instanceof org.hibernate.exception.LockTimeoutException) {
final PersistenceException converted = wrapLockException((HibernateException) cause, lockOptions);
handlePersistenceException(converted);
return converted;
} else if (cause instanceof org.hibernate.PessimisticLockException) {
final PersistenceException converted = wrapLockException((HibernateException) cause, lockOptions);
handlePersistenceException(converted);
return converted;
} else if (cause instanceof org.hibernate.QueryTimeoutException) {
final QueryTimeoutException converted = new QueryTimeoutException(cause.getMessage(), cause);
handlePersistenceException(converted);
return converted;
} else if (cause instanceof ObjectNotFoundException) {
final EntityNotFoundException converted = new EntityNotFoundException(cause.getMessage());
handlePersistenceException(converted);
return converted;
} else if (cause instanceof org.hibernate.NonUniqueObjectException) {
final EntityExistsException converted = new EntityExistsException(cause.getMessage());
handlePersistenceException(converted);
return converted;
} else if (cause instanceof org.hibernate.NonUniqueResultException) {
final NonUniqueResultException converted = new NonUniqueResultException(cause.getMessage());
handlePersistenceException(converted);
return converted;
} else if (cause instanceof UnresolvableObjectException) {
final EntityNotFoundException converted = new EntityNotFoundException(cause.getMessage());
handlePersistenceException(converted);
return converted;
} else if (cause instanceof QueryException) {
return new IllegalArgumentException(cause);
} else if (cause instanceof MultipleBagFetchException) {
return new IllegalArgumentException(cause);
} else if (cause instanceof TransientObjectException) {
try {
sharedSessionContract.markForRollbackOnly();
} catch (Exception ne) {
// we do not want the subsequent exception to swallow the original one
log.unableToMarkForRollbackOnTransientObjectException(ne);
}
// Spec 3.2.3 Synchronization rules
return new IllegalStateException(e);
} else {
final PersistenceException converted = new PersistenceException(cause);
handlePersistenceException(converted);
return converted;
}
}
use of org.hibernate.loader.MultipleBagFetchException in project hibernate-orm by hibernate.
the class AbstractLoadQueryDetails method generate.
/**
* Main entry point for properly handling the FROM clause and and joins and restrictions
*/
protected void generate() {
// There are 2 high-level requirements to perform here:
// 1) Determine the SQL required to carry out the given LoadPlan (and fulfill
// {@code LoadQueryDetails#getSqlStatement()}). SelectStatementBuilder collects the ongoing efforts to
// build the needed SQL.
// 2) Determine how to read information out of the ResultSet resulting from executing the indicated SQL
// (the SQL aliases). ReaderCollector and friends are where this work happens, ultimately
// producing a ResultSetProcessor
final SelectStatementBuilder select = new SelectStatementBuilder(queryProcessor.getSessionFactory().getDialect());
// LoadPlan is broken down into 2 high-level pieces that we need to process here.
//
// First is the QuerySpaces, which roughly equates to the SQL FROM-clause. We'll cycle through
// those first, generating aliases into the AliasContext in addition to writing SQL FROM-clause information
// into SelectStatementBuilder. The AliasContext is populated here and the reused while process the SQL
// SELECT-clause into the SelectStatementBuilder and then again also to build the ResultSetProcessor
applyRootReturnTableFragments(select);
if (shouldApplyRootReturnFilterBeforeKeyRestriction()) {
applyRootReturnFilterRestrictions(select);
// add restrictions...
// first, the load key restrictions (which entity(s)/collection(s) do we want to load?)
applyKeyRestriction(select, getRootTableAlias(), keyColumnNames, getQueryBuildingParameters().getBatchSize());
} else {
// add restrictions...
// first, the load key restrictions (which entity(s)/collection(s) do we want to load?)
applyKeyRestriction(select, getRootTableAlias(), keyColumnNames, getQueryBuildingParameters().getBatchSize());
applyRootReturnFilterRestrictions(select);
}
applyRootReturnWhereJoinRestrictions(select);
applyRootReturnOrderByFragments(select);
// then move on to joins...
applyRootReturnSelectFragments(select);
queryProcessor.processQuerySpaceJoins(getRootQuerySpace(), select);
// Next, we process the Returns and Fetches building the SELECT clause and at the same time building
// Readers for reading the described results out of a SQL ResultSet
FetchStats fetchStats = null;
if (FetchSource.class.isInstance(rootReturn)) {
fetchStats = queryProcessor.processFetches((FetchSource) rootReturn, select, getReaderCollector());
} else if (CollectionReturn.class.isInstance(rootReturn)) {
final CollectionReturn collectionReturn = (CollectionReturn) rootReturn;
if (collectionReturn.getElementGraph() != null) {
fetchStats = queryProcessor.processFetches(collectionReturn.getElementGraph(), select, getReaderCollector());
}
// TODO: what about index???
}
if (fetchStats != null && fetchStats.getJoinedBagAttributeFetches().size() > 1) {
final List<String> bagRoles = new ArrayList<>();
for (CollectionAttributeFetch bagFetch : fetchStats.getJoinedBagAttributeFetches()) {
bagRoles.add(bagFetch.getCollectionPersister().getRole());
}
throw new MultipleBagFetchException(bagRoles);
}
LoadPlanTreePrinter.INSTANCE.logTree(loadPlan, queryProcessor.getAliasResolutionContext());
this.sqlStatement = select.toStatementString();
this.resultSetProcessor = new ResultSetProcessorImpl(loadPlan, queryProcessor.getAliasResolutionContext(), getReaderCollector().buildRowReader(), shouldUseOptionalEntityInstance(), isSubselectLoadingEnabled(fetchStats));
}
Aggregations