use of org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn in project hibernate-orm by hibernate.
the class NativeQueryImpl method beforeQuery.
@Override
protected void beforeQuery() {
prepareQueryReturnsIfNecessary();
boolean noReturns = queryReturns == null || queryReturns.isEmpty();
if (noReturns) {
this.autoDiscoverTypes = true;
} else {
for (NativeSQLQueryReturn queryReturn : queryReturns) {
if (queryReturn instanceof NativeSQLQueryScalarReturn) {
NativeSQLQueryScalarReturn scalar = (NativeSQLQueryScalarReturn) queryReturn;
if (scalar.getType() == null) {
autoDiscoverTypes = true;
break;
}
} else if (NativeSQLQueryConstructorReturn.class.isInstance(queryReturn)) {
autoDiscoverTypes = true;
break;
}
}
}
super.beforeQuery();
if (getSynchronizedQuerySpaces() != null && !getSynchronizedQuerySpaces().isEmpty()) {
// perform a partial flush according to the defined query spaces, no need to do a full flush.
return;
}
// NOTE : this was added for JPA initially. Perhaps we want to only do this from JPA usage?
if (shouldFlush()) {
getProducer().flush();
}
}
use of org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn in project hibernate-orm by hibernate.
the class ResultSetMappingBinder method extractReturnDescription.
// todo : look to add query/resultset-mapping name to exception messages here.
// needs a kind of "context", i.e.:
// "Unable to resolve type [%s] specified for native query scalar return"
// becomes
// "Unable to resolve type [%s] specified for native query scalar return as part of [query|resultset-mapping] [name]"
//
// MappingException already carries origin, adding the query/resultset-mapping name pinpoints the location :)
public static NativeSQLQueryScalarReturn extractReturnDescription(JaxbHbmNativeQueryScalarReturnType rtnSource, HbmLocalMetadataBuildingContext context) {
final String column = rtnSource.getColumn();
final String typeName = rtnSource.getType();
Type type = null;
if (typeName != null) {
type = context.getMetadataCollector().getTypeResolver().heuristicType(typeName);
if (type == null) {
throw new MappingException(String.format("Unable to resolve type [%s] specified for native query scalar return", typeName), context.getOrigin());
}
}
return new NativeSQLQueryScalarReturn(column, type);
}
use of org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn in project hibernate-orm by hibernate.
the class ResultsetMappingSecondPass method doSecondPass.
@Override
public void doSecondPass(Map persistentClasses) throws MappingException {
//TODO add parameters checkings
if (ann == null)
return;
ResultSetMappingDefinition definition = new ResultSetMappingDefinition(ann.name());
LOG.debugf("Binding result set mapping: %s", definition.getName());
int entityAliasIndex = 0;
for (EntityResult entity : ann.entities()) {
//TODO parameterize lock mode?
List<FieldResult> properties = new ArrayList<FieldResult>();
List<String> propertyNames = new ArrayList<String>();
for (FieldResult field : entity.fields()) {
//use an ArrayList cause we might have several columns per root property
String name = field.name();
if (name.indexOf('.') == -1) {
//regular property
properties.add(field);
propertyNames.add(name);
} else {
/**
* Reorder properties
* 1. get the parent property
* 2. list all the properties following the expected one in the parent property
* 3. calculate the lowest index and insert the property
*/
PersistentClass pc = context.getMetadataCollector().getEntityBinding(entity.entityClass().getName());
if (pc == null) {
throw new MappingException(String.format(Locale.ENGLISH, "Could not resolve entity [%s] referenced in SqlResultSetMapping [%s]", entity.entityClass().getName(), ann.name()));
}
int dotIndex = name.lastIndexOf('.');
String reducedName = name.substring(0, dotIndex);
Iterator parentPropItr = getSubPropertyIterator(pc, reducedName);
List<String> followers = getFollowers(parentPropItr, reducedName, name);
int index = propertyNames.size();
for (String follower : followers) {
int currentIndex = getIndexOfFirstMatchingProperty(propertyNames, follower);
index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
}
propertyNames.add(index, name);
properties.add(index, field);
}
}
Set<String> uniqueReturnProperty = new HashSet<String>();
Map<String, ArrayList<String>> propertyResultsTmp = new HashMap<String, ArrayList<String>>();
for (Object property : properties) {
final FieldResult propertyresult = (FieldResult) property;
final String name = propertyresult.name();
if ("class".equals(name)) {
throw new MappingException("class is not a valid property name to use in a @FieldResult, use @Entity(discriminatorColumn) instead");
}
if (uniqueReturnProperty.contains(name)) {
throw new MappingException("duplicate @FieldResult for property " + name + " on @Entity " + entity.entityClass().getName() + " in " + ann.name());
}
uniqueReturnProperty.add(name);
final String quotingNormalizedColumnName = normalizeColumnQuoting(propertyresult.column());
String key = StringHelper.root(name);
ArrayList<String> intermediateResults = propertyResultsTmp.get(key);
if (intermediateResults == null) {
intermediateResults = new ArrayList<String>();
propertyResultsTmp.put(key, intermediateResults);
}
intermediateResults.add(quotingNormalizedColumnName);
}
Map<String, String[]> propertyResults = new HashMap<String, String[]>();
for (Map.Entry<String, ArrayList<String>> entry : propertyResultsTmp.entrySet()) {
propertyResults.put(entry.getKey(), entry.getValue().toArray(new String[entry.getValue().size()]));
}
if (!BinderHelper.isEmptyAnnotationValue(entity.discriminatorColumn())) {
final String quotingNormalizedName = normalizeColumnQuoting(entity.discriminatorColumn());
propertyResults.put("class", new String[] { quotingNormalizedName });
}
if (propertyResults.isEmpty()) {
propertyResults = java.util.Collections.emptyMap();
}
NativeSQLQueryRootReturn result = new NativeSQLQueryRootReturn("alias" + entityAliasIndex++, entity.entityClass().getName(), propertyResults, LockMode.READ);
definition.addQueryReturn(result);
}
for (ColumnResult column : ann.columns()) {
definition.addQueryReturn(new NativeSQLQueryScalarReturn(normalizeColumnQuoting(column.name()), column.type() != null ? context.getMetadataCollector().getTypeResolver().heuristicType(column.type().getName()) : null));
}
for (ConstructorResult constructorResult : ann.classes()) {
List<NativeSQLQueryScalarReturn> columnReturns = new ArrayList<NativeSQLQueryScalarReturn>();
for (ColumnResult columnResult : constructorResult.columns()) {
columnReturns.add(new NativeSQLQueryScalarReturn(normalizeColumnQuoting(columnResult.name()), columnResult.type() != null ? context.getMetadataCollector().getTypeResolver().heuristicType(columnResult.type().getName()) : null));
}
definition.addQueryReturn(new NativeSQLQueryConstructorReturn(constructorResult.targetClass(), columnReturns));
}
if (isDefault) {
context.getMetadataCollector().addDefaultResultSetMapping(definition);
} else {
context.getMetadataCollector().addResultSetMapping(definition);
}
}
use of org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn in project hibernate-orm by hibernate.
the class SQLQueryReturnProcessor method generateCustomReturns.
public List<Return> generateCustomReturns(boolean queryHadAliases) {
List<Return> customReturns = new ArrayList<Return>();
Map<String, Return> customReturnsByAlias = new HashMap<String, Return>();
for (NativeSQLQueryReturn queryReturn : queryReturns) {
if (queryReturn instanceof NativeSQLQueryScalarReturn) {
NativeSQLQueryScalarReturn rtn = (NativeSQLQueryScalarReturn) queryReturn;
customReturns.add(new ScalarReturn(rtn.getType(), rtn.getColumnAlias()));
} else if (queryReturn instanceof NativeSQLQueryRootReturn) {
NativeSQLQueryRootReturn rtn = (NativeSQLQueryRootReturn) queryReturn;
String alias = rtn.getAlias();
EntityAliases entityAliases;
if (queryHadAliases || hasPropertyResultMap(alias)) {
entityAliases = new DefaultEntityAliases((Map) entityPropertyResultMaps.get(alias), (SQLLoadable) alias2Persister.get(alias), (String) alias2Suffix.get(alias));
} else {
entityAliases = new ColumnEntityAliases((Map) entityPropertyResultMaps.get(alias), (SQLLoadable) alias2Persister.get(alias), (String) alias2Suffix.get(alias));
}
RootReturn customReturn = new RootReturn(alias, rtn.getReturnEntityName(), entityAliases, rtn.getLockMode());
customReturns.add(customReturn);
customReturnsByAlias.put(rtn.getAlias(), customReturn);
} else if (queryReturn instanceof NativeSQLQueryCollectionReturn) {
NativeSQLQueryCollectionReturn rtn = (NativeSQLQueryCollectionReturn) queryReturn;
String alias = rtn.getAlias();
SQLLoadableCollection persister = (SQLLoadableCollection) alias2CollectionPersister.get(alias);
boolean isEntityElements = persister.getElementType().isEntityType();
CollectionAliases collectionAliases;
EntityAliases elementEntityAliases = null;
if (queryHadAliases || hasPropertyResultMap(alias)) {
collectionAliases = new GeneratedCollectionAliases((Map) collectionPropertyResultMaps.get(alias), (SQLLoadableCollection) alias2CollectionPersister.get(alias), (String) alias2CollectionSuffix.get(alias));
if (isEntityElements) {
elementEntityAliases = new DefaultEntityAliases((Map) entityPropertyResultMaps.get(alias), (SQLLoadable) alias2Persister.get(alias), (String) alias2Suffix.get(alias));
}
} else {
collectionAliases = new ColumnCollectionAliases((Map) collectionPropertyResultMaps.get(alias), (SQLLoadableCollection) alias2CollectionPersister.get(alias));
if (isEntityElements) {
elementEntityAliases = new ColumnEntityAliases((Map) entityPropertyResultMaps.get(alias), (SQLLoadable) alias2Persister.get(alias), (String) alias2Suffix.get(alias));
}
}
CollectionReturn customReturn = new CollectionReturn(alias, rtn.getOwnerEntityName(), rtn.getOwnerProperty(), collectionAliases, elementEntityAliases, rtn.getLockMode());
customReturns.add(customReturn);
customReturnsByAlias.put(rtn.getAlias(), customReturn);
} else if (queryReturn instanceof NativeSQLQueryJoinReturn) {
NativeSQLQueryJoinReturn rtn = (NativeSQLQueryJoinReturn) queryReturn;
String alias = rtn.getAlias();
FetchReturn customReturn;
NonScalarReturn ownerCustomReturn = (NonScalarReturn) customReturnsByAlias.get(rtn.getOwnerAlias());
if (alias2CollectionPersister.containsKey(alias)) {
SQLLoadableCollection persister = (SQLLoadableCollection) alias2CollectionPersister.get(alias);
boolean isEntityElements = persister.getElementType().isEntityType();
CollectionAliases collectionAliases;
EntityAliases elementEntityAliases = null;
if (queryHadAliases || hasPropertyResultMap(alias)) {
collectionAliases = new GeneratedCollectionAliases((Map) collectionPropertyResultMaps.get(alias), persister, (String) alias2CollectionSuffix.get(alias));
if (isEntityElements) {
elementEntityAliases = new DefaultEntityAliases((Map) entityPropertyResultMaps.get(alias), (SQLLoadable) alias2Persister.get(alias), (String) alias2Suffix.get(alias));
}
} else {
collectionAliases = new ColumnCollectionAliases((Map) collectionPropertyResultMaps.get(alias), persister);
if (isEntityElements) {
elementEntityAliases = new ColumnEntityAliases((Map) entityPropertyResultMaps.get(alias), (SQLLoadable) alias2Persister.get(alias), (String) alias2Suffix.get(alias));
}
}
customReturn = new CollectionFetchReturn(alias, ownerCustomReturn, rtn.getOwnerProperty(), collectionAliases, elementEntityAliases, rtn.getLockMode());
} else {
EntityAliases entityAliases;
if (queryHadAliases || hasPropertyResultMap(alias)) {
entityAliases = new DefaultEntityAliases((Map) entityPropertyResultMaps.get(alias), (SQLLoadable) alias2Persister.get(alias), (String) alias2Suffix.get(alias));
} else {
entityAliases = new ColumnEntityAliases((Map) entityPropertyResultMaps.get(alias), (SQLLoadable) alias2Persister.get(alias), (String) alias2Suffix.get(alias));
}
customReturn = new EntityFetchReturn(alias, entityAliases, ownerCustomReturn, rtn.getOwnerProperty(), rtn.getLockMode());
}
customReturns.add(customReturn);
customReturnsByAlias.put(alias, customReturn);
} else if (NativeSQLQueryConstructorReturn.class.isInstance(queryReturn)) {
final NativeSQLQueryConstructorReturn constructorReturn = (NativeSQLQueryConstructorReturn) queryReturn;
final ScalarReturn[] scalars = new ScalarReturn[constructorReturn.getColumnReturns().length];
int i = 0;
for (NativeSQLQueryScalarReturn scalarReturn : constructorReturn.getColumnReturns()) {
scalars[i++] = new ScalarReturn(scalarReturn.getType(), scalarReturn.getColumnAlias());
}
customReturns.add(new ConstructorReturn(constructorReturn.getTargetClass(), scalars));
} else {
throw new IllegalStateException("Unrecognized NativeSQLQueryReturn concrete type : " + queryReturn);
}
}
return customReturns;
}
use of org.hibernate.engine.query.spi.sql.NativeSQLQueryScalarReturn in project hibernate-orm by hibernate.
the class NativeSQLQueryReturnEqualsAndHashCodeTest method testNativeSQLQueryScalarReturn.
@Test
public void testNativeSQLQueryScalarReturn() {
NativeSQLQueryScalarReturn typeNoAlias = new NativeSQLQueryScalarReturn(null, sessionFactory().getTypeResolver().basic("int"));
NativeSQLQueryScalarReturn aliasNoType = new NativeSQLQueryScalarReturn("abc", null);
NativeSQLQueryScalarReturn aliasTypeInt = new NativeSQLQueryScalarReturn("abc", sessionFactory().getTypeResolver().basic("int"));
NativeSQLQueryScalarReturn aliasTypeLong = new NativeSQLQueryScalarReturn("abc", sessionFactory().getTypeResolver().basic("long"));
NativeSQLQueryScalarReturn aliasTypeLongClass = new NativeSQLQueryScalarReturn("abc", sessionFactory().getTypeResolver().basic(Long.class.getName()));
NativeSQLQueryScalarReturn aliasTypeString = new NativeSQLQueryScalarReturn("abc", sessionFactory().getTypeResolver().basic("string"));
NativeSQLQueryScalarReturn aliasTypeStringClass = new NativeSQLQueryScalarReturn("abc", sessionFactory().getTypeResolver().basic(String.class.getName()));
check(false, typeNoAlias, aliasNoType);
check(false, typeNoAlias, aliasTypeInt);
check(false, typeNoAlias, aliasTypeLong);
check(false, typeNoAlias, aliasTypeLongClass);
check(false, typeNoAlias, aliasTypeString);
check(false, typeNoAlias, aliasTypeStringClass);
check(false, aliasNoType, aliasTypeInt);
check(false, aliasNoType, aliasTypeLong);
check(false, aliasNoType, aliasTypeLongClass);
check(false, aliasNoType, aliasTypeString);
check(false, aliasNoType, aliasTypeStringClass);
check(false, aliasTypeInt, aliasTypeLong);
check(false, aliasTypeInt, aliasTypeLongClass);
check(false, aliasTypeInt, aliasTypeString);
check(false, aliasTypeInt, aliasTypeStringClass);
check(true, aliasTypeLong, aliasTypeLongClass);
check(false, aliasTypeLong, aliasTypeString);
check(false, aliasTypeLong, aliasTypeStringClass);
check(false, aliasTypeLongClass, aliasTypeString);
check(false, aliasTypeLongClass, aliasTypeStringClass);
check(true, aliasTypeString, aliasTypeStringClass);
check(true, typeNoAlias, new NativeSQLQueryScalarReturn(null, sessionFactory().getTypeResolver().basic("int")));
check(true, aliasNoType, new NativeSQLQueryScalarReturn("abc", null));
check(true, aliasTypeInt, new NativeSQLQueryScalarReturn("abc", sessionFactory().getTypeResolver().basic("int")));
check(true, aliasTypeLong, new NativeSQLQueryScalarReturn("abc", sessionFactory().getTypeResolver().basic("long")));
check(true, aliasTypeLongClass, new NativeSQLQueryScalarReturn("abc", sessionFactory().getTypeResolver().basic(Long.class.getName())));
check(true, aliasTypeString, new NativeSQLQueryScalarReturn("abc", sessionFactory().getTypeResolver().basic("string")));
check(true, aliasTypeStringClass, new NativeSQLQueryScalarReturn("abc", sessionFactory().getTypeResolver().basic(String.class.getName())));
}
Aggregations