org.hibernate.dialect.lock.LockingStrategyException#org.hibernate.loader.MultipleBagFetchException源码实例Demo

下面列出了org.hibernate.dialect.lock.LockingStrategyException#org.hibernate.loader.MultipleBagFetchException 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。

@Test
void multipleBagFetchException() {
  log.info("MultipleBagFetchException on @EntityGraph with multiple attribute nodes");

  assertThatThrownBy(() -> bookRepository.findByPublicationDateBetween(
      LocalDate.parse("2000-01-01"), LocalDate.parse("2020-01-01"),
      Sort.by(ASC, "publicationDate")))
      .hasRootCauseInstanceOf(MultipleBagFetchException.class)
      .hasMessageContaining("cannot simultaneously fetch multiple bags");
  //Trying to fetch multiple many-to-many relations
  //List<Author> authors and List<Category> categories
  //that both have type List results in exception
  //org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
}
 
源代码2 项目: lams   文件: AbstractLoadQueryDetails.java
/**
 * 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 )
	);
}