use of org.hibernate.boot.jaxb.hbm.internal.ImplicitResultSetMappingDefinition in project hibernate-orm by hibernate.
the class NamedQueryBinder method processNamedNativeQuery.
public static void processNamedNativeQuery(final HbmLocalMetadataBuildingContext context, JaxbHbmNamedNativeQueryType namedQueryBinding, String prefix) {
final String queryName = prefix + namedQueryBinding.getName();
final NamedSQLQueryDefinitionBuilder builder = new NamedSQLQueryDefinitionBuilder().setName(queryName).setComment(namedQueryBinding.getComment()).setCacheable(namedQueryBinding.isCacheable()).setCacheMode(namedQueryBinding.getCacheMode()).setCacheRegion(namedQueryBinding.getCacheRegion()).setTimeout(namedQueryBinding.getTimeout()).setReadOnly(namedQueryBinding.isReadOnly()).setFlushMode(namedQueryBinding.getFlushMode()).setFetchSize(namedQueryBinding.getFetchSize()).setCallable(namedQueryBinding.isCallable()).setResultSetRef(namedQueryBinding.getResultsetRef());
final ImplicitResultSetMappingDefinition.Builder implicitResultSetMappingBuilder = new ImplicitResultSetMappingDefinition.Builder(queryName);
boolean foundQuery = false;
for (Object content : namedQueryBinding.getContent()) {
final boolean wasQuery = processNamedQueryContentItem(content, builder, implicitResultSetMappingBuilder, namedQueryBinding, context);
if (wasQuery) {
foundQuery = true;
}
}
if (!foundQuery) {
throw new org.hibernate.boot.MappingException(String.format("Named native query [%s] did not specify query string", namedQueryBinding.getName()), context.getOrigin());
}
if (implicitResultSetMappingBuilder.hasAnyReturns()) {
if (StringHelper.isNotEmpty(namedQueryBinding.getResultsetRef())) {
throw new org.hibernate.boot.MappingException(String.format("Named native query [%s] specified both a resultset-ref and an inline mapping of results", namedQueryBinding.getName()), context.getOrigin());
}
// Building a ResultSet mapping needs access to entity bindings for any entity
// returns it defines. But binding for those entities may have not been
// completed yet. For "normal" ResultSet mappings, this is already handled by
// the fact that MetadataSourceProcessor#processResultSetMappings() is called
// after all entity hierarchies have been processed. However, here we are in
// the middle of processing named-queries (either top-level or entity-level)
// and have no guarantee that any entity bindings we may need here are bound.
// So we add the second-pass to bind the implicit resultSet mapping.
//
// It is possible to know here whether the second-pass is needed or whether we
// can immediately bind the ResultSet mapping.
// todo : consider implementing this (^^) checking
final ImplicitResultSetMappingDefinition implicitResultSetMappingDefinition = implicitResultSetMappingBuilder.build();
builder.setResultSetRef(implicitResultSetMappingDefinition.getName());
context.getMetadataCollector().addSecondPass(new SecondPass() {
@Override
public void doSecondPass(Map persistentClasses) throws MappingException {
final ResultSetMappingDefinition resultSetMappingDefinition = ResultSetMappingBinder.bind(implicitResultSetMappingDefinition, context);
context.getMetadataCollector().addResultSetMapping(resultSetMappingDefinition);
NativeSQLQueryReturn[] newQueryReturns = resultSetMappingDefinition.getQueryReturns();
final NamedSQLQueryDefinition queryDefinition = context.getMetadataCollector().getNamedNativeQueryDefinition(queryName);
if (queryDefinition != null) {
queryDefinition.addQueryReturns(newQueryReturns);
}
}
});
}
context.getMetadataCollector().addNamedNativeQuery(builder.createNamedQueryDefinition());
}
Aggregations