use of org.hibernate.boot.MappingException 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.boot.MappingException in project hibernate-orm by hibernate.
the class ModelBinder method determineTable.
private Identifier determineTable(MappingDocument mappingDocument, SingularAttributeSourceEmbedded embeddedAttributeSource) {
Identifier tableName = null;
for (AttributeSource attributeSource : embeddedAttributeSource.getEmbeddableSource().attributeSources()) {
final Identifier determinedName;
if (RelationalValueSourceContainer.class.isInstance(attributeSource)) {
determinedName = determineTable(mappingDocument, embeddedAttributeSource.getAttributeRole().getFullPath(), (RelationalValueSourceContainer) attributeSource);
} else if (SingularAttributeSourceEmbedded.class.isInstance(attributeSource)) {
determinedName = determineTable(mappingDocument, (SingularAttributeSourceEmbedded) attributeSource);
} else if (SingularAttributeSourceAny.class.isInstance(attributeSource)) {
determinedName = determineTable(mappingDocument, attributeSource.getAttributeRole().getFullPath(), ((SingularAttributeSourceAny) attributeSource).getKeySource().getRelationalValueSources());
} else {
continue;
}
if (EqualsHelper.equals(tableName, determinedName)) {
continue;
}
if (tableName != null) {
throw new MappingException(String.format(Locale.ENGLISH, "Attribute [%s] referenced columns from multiple tables: %s, %s", embeddedAttributeSource.getAttributeRole().getFullPath(), tableName, determinedName), mappingDocument.getOrigin());
}
tableName = determinedName;
}
return tableName;
}
use of org.hibernate.boot.MappingException in project hibernate-orm by hibernate.
the class ModelBinder method createManyToOneAttribute.
private Property createManyToOneAttribute(MappingDocument sourceDocument, SingularAttributeSourceManyToOne manyToOneSource, ManyToOne manyToOneBinding, String containingClassName) {
final String attributeName = manyToOneSource.getName();
final String referencedEntityName;
if (manyToOneSource.getReferencedEntityName() != null) {
referencedEntityName = manyToOneSource.getReferencedEntityName();
} else {
Class reflectedPropertyClass = Helper.reflectedPropertyClass(sourceDocument, containingClassName, attributeName);
if (reflectedPropertyClass != null) {
referencedEntityName = reflectedPropertyClass.getName();
} else {
prepareValueTypeViaReflection(sourceDocument, manyToOneBinding, containingClassName, attributeName, manyToOneSource.getAttributeRole());
referencedEntityName = manyToOneBinding.getTypeName();
}
}
if (manyToOneSource.isUnique()) {
manyToOneBinding.markAsLogicalOneToOne();
}
bindManyToOneAttribute(sourceDocument, manyToOneSource, manyToOneBinding, referencedEntityName);
final String propertyRef = manyToOneBinding.getReferencedPropertyName();
if (propertyRef != null) {
handlePropertyReference(sourceDocument, manyToOneBinding.getReferencedEntityName(), propertyRef, true, "<many-to-one name=\"" + manyToOneSource.getName() + "\"/>");
}
Property prop = new Property();
prop.setValue(manyToOneBinding);
bindProperty(sourceDocument, manyToOneSource, prop);
if (StringHelper.isNotEmpty(manyToOneSource.getCascadeStyleName())) {
// a "validation" fails since it loses "context"
if (manyToOneSource.getCascadeStyleName().contains("delete-orphan")) {
if (!manyToOneBinding.isLogicalOneToOne()) {
throw new MappingException(String.format(Locale.ENGLISH, "many-to-one attribute [%s] specified delete-orphan but is not specified as unique; " + "remove delete-orphan cascading or specify unique=\"true\"", manyToOneSource.getAttributeRole().getFullPath()), sourceDocument.getOrigin());
}
}
}
return prop;
}
use of org.hibernate.boot.MappingException in project hibernate-orm by hibernate.
the class ResultSetMappingBinder method extractPropertyResults.
@SuppressWarnings("unchecked")
private static Map<String, String[]> extractPropertyResults(String alias, NativeQueryNonScalarRootReturn rtnSource, PersistentClass pc, HbmLocalMetadataBuildingContext context) {
if (CollectionHelper.isEmpty(rtnSource.getReturnProperty())) {
return null;
}
final HashMap results = new HashMap();
List<JaxbHbmNativeQueryPropertyReturnType> propertyReturnSources = new ArrayList<JaxbHbmNativeQueryPropertyReturnType>();
List<String> propertyNames = new ArrayList<String>();
for (JaxbHbmNativeQueryPropertyReturnType propertyReturnSource : rtnSource.getReturnProperty()) {
final int dotPosition = propertyReturnSource.getName().lastIndexOf('.');
if (pc == null || dotPosition == -1) {
propertyReturnSources.add(propertyReturnSource);
propertyNames.add(propertyReturnSource.getName());
} else {
final String reducedName = propertyReturnSource.getName().substring(0, dotPosition);
final Value value = pc.getRecursiveProperty(reducedName).getValue();
Iterator parentPropItr;
if (value instanceof Component) {
final Component comp = (Component) value;
parentPropItr = comp.getPropertyIterator();
} else if (value instanceof ToOne) {
final ToOne toOne = (ToOne) value;
final PersistentClass referencedPc = context.getMetadataCollector().getEntityBinding(toOne.getReferencedEntityName());
if (toOne.getReferencedPropertyName() != null) {
try {
parentPropItr = ((Component) referencedPc.getRecursiveProperty(toOne.getReferencedPropertyName()).getValue()).getPropertyIterator();
} catch (ClassCastException e) {
throw new MappingException("dotted notation reference neither a component nor a many/one to one", e, context.getOrigin());
}
} else {
try {
if (referencedPc.getIdentifierMapper() == null) {
parentPropItr = ((Component) referencedPc.getIdentifierProperty().getValue()).getPropertyIterator();
} else {
parentPropItr = referencedPc.getIdentifierMapper().getPropertyIterator();
}
} catch (ClassCastException e) {
throw new MappingException("dotted notation reference neither a component nor a many/one to one", e, context.getOrigin());
}
}
} else {
throw new MappingException("dotted notation reference neither a component nor a many/one to one", context.getOrigin());
}
boolean hasFollowers = false;
List<String> followers = new ArrayList<String>();
while (parentPropItr.hasNext()) {
final Property parentProperty = (Property) parentPropItr.next();
final String currentPropertyName = parentProperty.getName();
final String currentName = reducedName + '.' + currentPropertyName;
if (hasFollowers) {
followers.add(currentName);
}
if (propertyReturnSource.getName().equals(currentName)) {
hasFollowers = true;
}
}
int index = propertyNames.size();
for (String follower : followers) {
int currentIndex = getIndexOfFirstMatchingProperty(propertyNames, follower);
index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
}
propertyNames.add(index, propertyReturnSource.getName());
propertyReturnSources.add(index, propertyReturnSource);
}
}
Set<String> uniqueReturnProperty = new HashSet<String>();
for (JaxbHbmNativeQueryPropertyReturnType propertyReturnBinding : propertyReturnSources) {
final String name = propertyReturnBinding.getName();
if ("class".equals(name)) {
throw new MappingException("class is not a valid property name to use in a <return-property>, use <return-discriminator> instead", context.getOrigin());
}
//TODO: validate existing of property with the chosen name. (secondpass )
ArrayList allResultColumns = extractResultColumns(propertyReturnBinding);
if (allResultColumns.isEmpty()) {
throw new MappingException(String.format(Locale.ENGLISH, "return-property [alias=%s, property=%s] must specify at least one column or return-column name", alias, propertyReturnBinding.getName()), context.getOrigin());
}
if (uniqueReturnProperty.contains(name)) {
throw new MappingException(String.format(Locale.ENGLISH, "Duplicate return-property [alias=%s] : %s", alias, propertyReturnBinding.getName()), context.getOrigin());
}
uniqueReturnProperty.add(name);
// the issue here is that for <return-join/> representing an entity collection,
// the collection element values (the property values of the associated entity)
// are represented as 'element.{propertyname}'. Thus the StringHelper.root()
// here puts everything under 'element' (which additionally has significant
// meaning). Probably what we need to do is to something like this instead:
// String root = StringHelper.root( name );
// String key = root; // by default
// if ( !root.equals( name ) ) {
// // we had a dot
// if ( !root.equals( alias ) {
// // the root does not apply to the specific alias
// if ( "elements".equals( root ) {
// // we specifically have a <return-join/> representing an entity collection
// // and this <return-property/> is one of that entity's properties
// key = name;
// }
// }
// }
// but I am not clear enough on the intended purpose of this code block, especially
// in relation to the "Reorder properties" code block above...
// String key = StringHelper.root( name );
ArrayList intermediateResults = (ArrayList) results.get(name);
if (intermediateResults == null) {
results.put(name, allResultColumns);
} else {
intermediateResults.addAll(allResultColumns);
}
}
for (Object o : results.entrySet()) {
Map.Entry entry = (Map.Entry) o;
if (entry.getValue() instanceof ArrayList) {
ArrayList list = (ArrayList) entry.getValue();
entry.setValue(list.toArray(new String[list.size()]));
}
}
return results.isEmpty() ? Collections.EMPTY_MAP : results;
}
use of org.hibernate.boot.MappingException in project hibernate-orm by hibernate.
the class EntityHierarchySourceImpl method interpretMultiTenancySource.
private static MultiTenancySource interpretMultiTenancySource(final RootEntitySourceImpl rootEntitySource) {
final JaxbHbmMultiTenancyType jaxbMultiTenancy = rootEntitySource.jaxbEntityMapping().getMultiTenancy();
if (jaxbMultiTenancy == null) {
return null;
}
final RelationalValueSource relationalValueSource = RelationalValueSourceHelper.buildValueSource(rootEntitySource.sourceMappingDocument(), null, new RelationalValueSourceHelper.AbstractColumnsAndFormulasSource() {
@Override
public XmlElementMetadata getSourceType() {
return XmlElementMetadata.MULTI_TENANCY;
}
@Override
public String getSourceName() {
return null;
}
@Override
public String getFormulaAttribute() {
return jaxbMultiTenancy.getFormulaAttribute();
}
@Override
public String getColumnAttribute() {
return jaxbMultiTenancy.getColumnAttribute();
}
private List columnOrFormulas;
@Override
public List getColumnOrFormulaElements() {
if (columnOrFormulas == null) {
if (jaxbMultiTenancy.getColumn() != null) {
if (jaxbMultiTenancy.getFormula() != null) {
throw new MappingException(String.format(Locale.ENGLISH, "discriminator mapping [%s] named both <column/> and <formula/>, but only one or other allowed", rootEntitySource.getEntityNamingSource().getEntityName()), rootEntitySource.sourceMappingDocument().getOrigin());
} else {
columnOrFormulas = Collections.singletonList(jaxbMultiTenancy.getColumn());
}
} else {
if (jaxbMultiTenancy.getFormula() != null) {
columnOrFormulas = Collections.singletonList(jaxbMultiTenancy.getColumn());
} else {
columnOrFormulas = Collections.emptyList();
}
}
}
return columnOrFormulas;
}
@Override
public Boolean isNullable() {
return false;
}
});
return new MultiTenancySource() {
@Override
public RelationalValueSource getRelationalValueSource() {
return relationalValueSource;
}
@Override
public boolean isShared() {
return jaxbMultiTenancy.isShared();
}
@Override
public boolean bindAsParameter() {
return jaxbMultiTenancy.isBindAsParam();
}
};
}
Aggregations