use of com.blazebit.persistence.spi.ExtendedAttribute in project blaze-persistence by Blazebit.
the class AbstractCommonQueryBuilder method getValuesExampleQuery.
private Query getValuesExampleQuery(Class<?> clazz, int valueCount, boolean identifiableReference, String valueClazzAttributeName, String prefix, String castedParameter, String[] attributes, StringBuilder valuesSb, ValuesStrategy strategy, String dummyTable, JoinNode valuesNode) {
String[] attributeParameter = new String[attributes.length];
// This size estimation roughly assumes a maximum attribute name length of 15
StringBuilder sb = new StringBuilder(50 + valueCount * prefix.length() * attributes.length * 50);
sb.append("SELECT ");
if (clazz == ValuesEntity.class) {
sb.append("e.");
attributeParameter[0] = mainQuery.dbmsDialect.needsCastParameters() ? castedParameter : "?";
sb.append(attributes[0]);
sb.append(',');
} else {
Map<String, ExtendedAttribute> mapping = mainQuery.metamodel.getManagedType(ExtendedManagedType.class, clazz).getAttributes();
StringBuilder paramBuilder = new StringBuilder();
for (int i = 0; i < attributes.length; i++) {
ExtendedAttribute entry;
if (valuesNode.isValueClazzSimpleValue()) {
entry = mapping.get(valueClazzAttributeName);
} else {
entry = mapping.get(attributes[i]);
}
Attribute attribute = entry.getAttribute();
String[] columnTypes;
if (valuesNode.getQualificationExpression() == null) {
columnTypes = entry.getColumnTypes();
} else {
Collection<String> types = entry.getJoinTable().getKeyColumnTypes().values();
columnTypes = types.toArray(new String[types.size()]);
}
attributeParameter[i] = getCastedParameters(paramBuilder, mainQuery.dbmsDialect, columnTypes);
// otherwise we would fetch all of the types attributes, but the VALUES clause can only ever contain the id
if (attribute.getPersistentAttributeType() != Attribute.PersistentAttributeType.BASIC && attribute.getPersistentAttributeType() != Attribute.PersistentAttributeType.EMBEDDED && valuesNode.getQualificationExpression() == null) {
ManagedType<?> managedAttributeType = mainQuery.metamodel.getManagedType(entry.getElementClass());
if (managedAttributeType == null || mainQuery.jpaProvider.needsElementCollectionIdCutoff() && valuesNode.getValuesLikeAttribute() != null && mapping.get(valuesNode.getValuesLikeAttribute()).getAttribute().getPersistentAttributeType() == Attribute.PersistentAttributeType.ELEMENT_COLLECTION) {
sb.append("e");
if (valuesNode.isValueClazzAttributeSingular()) {
sb.append('.');
sb.append(attributes[i]);
} else {
sb.append('_');
sb.append(valueClazzAttributeName.replace('.', '_'));
sb.append(attributes[i], valueClazzAttributeName.length(), attributes[i].length());
}
} else {
for (Attribute<?, ?> attributeTypeIdAttribute : JpaMetamodelUtils.getIdAttributes((IdentifiableType<?>) managedAttributeType)) {
sb.append("e");
if (valuesNode.isValueClazzAttributeSingular()) {
sb.append('.');
sb.append(attributes[i]);
} else {
sb.append('_');
sb.append(valueClazzAttributeName.replace('.', '_'));
sb.append(attributes[i], valueClazzAttributeName.length(), attributes[i].length());
}
sb.append('.');
sb.append(attributeTypeIdAttribute.getName());
}
}
} else {
if (valuesNode.getQualificationExpression() != null) {
sb.append(valuesNode.getQualificationExpression()).append('(');
}
sb.append("e");
if (valuesNode.isValueClazzAttributeSingular()) {
sb.append('.');
sb.append(attributes[i]);
} else {
sb.append('_');
sb.append(valueClazzAttributeName.replace('.', '_'));
sb.append(attributes[i], valueClazzAttributeName.length(), attributes[i].length());
}
if (valuesNode.getQualificationExpression() != null) {
sb.append('_').append(valuesNode.getQualificationExpression().toLowerCase()).append(')');
}
}
sb.append(',');
}
}
sb.setCharAt(sb.length() - 1, ' ');
sb.append("FROM ");
sb.append(clazz.getName());
sb.append(" e");
if (!valuesNode.isValueClazzAttributeSingular()) {
sb.append(" LEFT JOIN e.");
if (valuesNode.isValueClazzSimpleValue()) {
sb.append(valueClazzAttributeName);
} else {
sb.append(valuesNode.getValuesLikeAttribute());
}
sb.append(" e_");
if (valuesNode.isValueClazzSimpleValue()) {
sb.append(valueClazzAttributeName.replace('.', '_'));
} else {
sb.append(valuesNode.getValuesLikeAttribute().replace('.', '_'));
}
if (valuesNode.getQualificationExpression() != null) {
sb.append('_').append(valuesNode.getQualificationExpression().toLowerCase());
}
}
sb.append(" WHERE ");
joinManager.renderPlaceholderRequiringPredicate(sb, valuesNode, "e", false, false);
if (strategy == ValuesStrategy.SELECT_VALUES || strategy == ValuesStrategy.VALUES) {
valuesSb.append("(VALUES ");
} else if (strategy == ValuesStrategy.SELECT_UNION) {
// Nothing to do here
} else {
throw new IllegalArgumentException("Unsupported values strategy: " + strategy);
}
for (int i = 0; i < valueCount; i++) {
if (strategy == ValuesStrategy.SELECT_UNION) {
valuesSb.append(" union all select ");
} else {
valuesSb.append('(');
}
for (int j = 0; j < attributes.length; j++) {
valuesSb.append(attributeParameter[j]);
valuesSb.append(',');
}
if (strategy == ValuesStrategy.SELECT_UNION) {
valuesSb.setCharAt(valuesSb.length() - 1, ' ');
if (dummyTable != null) {
valuesSb.append("from ");
valuesSb.append(dummyTable);
valuesSb.append(' ');
}
} else {
valuesSb.setCharAt(valuesSb.length() - 1, ')');
valuesSb.append(',');
}
}
if (strategy == ValuesStrategy.SELECT_UNION) {
valuesSb.setCharAt(valuesSb.length() - 1, ' ');
} else {
valuesSb.setCharAt(valuesSb.length() - 1, ')');
}
String exampleQueryString = sb.toString();
return mainQuery.em.createQuery(exampleQueryString);
}
use of com.blazebit.persistence.spi.ExtendedAttribute in project blaze-persistence by Blazebit.
the class AbstractModificationCriteriaBuilder method returning.
@SuppressWarnings("unchecked")
public X returning(String cteAttribute, String modificationQueryAttribute) {
if (cteAttribute == null) {
throw new NullPointerException("cteAttribute");
}
if (modificationQueryAttribute == null) {
throw new NullPointerException("modificationQueryAttribute");
}
if (cteAttribute.isEmpty()) {
throw new IllegalArgumentException("Invalid empty cteAttribute");
}
if (modificationQueryAttribute.isEmpty()) {
throw new IllegalArgumentException("Invalid empty modificationQueryAttribute");
}
ExtendedAttribute attributeEntry = attributeEntries.get(cteAttribute);
if (attributeEntry == null) {
if (cteType.getAttribute(cteAttribute) != null) {
throw new IllegalArgumentException("Can't bind the embeddable cte attribute [" + cteAttribute + "] directly! Please bind the respective sub attributes.");
}
throw new IllegalArgumentException("The cte attribute [" + cteAttribute + "] does not exist!");
}
Class<?> queryAttrType;
if (isReturningEntityAliasAllowed && modificationQueryAttribute.equals(entityAlias)) {
// Our little special case, since there would be no other way to refer to the id as the object type
queryAttrType = entityType.getJavaType();
Attribute<?, ?> idAttribute = JpaMetamodelUtils.getSingleIdAttribute(entityType);
modificationQueryAttribute = idAttribute.getName();
} else {
JpaMetamodelAccessor jpaMetamodelAccessor = mainQuery.jpaProvider.getJpaMetamodelAccessor();
AttributePath queryAttributePath = jpaMetamodelAccessor.getBasicAttributePath(getMetamodel(), entityType, modificationQueryAttribute);
queryAttrType = queryAttributePath.getAttributeClass();
}
Class<?> cteAttrType = attributeEntry.getElementClass();
// but if it already supports the returning clause, it can only also support returning all columns
if (!cteAttrType.isAssignableFrom(queryAttrType)) {
throw new IllegalArgumentException("The given cte attribute '" + cteAttribute + "' with the type '" + cteAttrType.getName() + "'" + " can not be assigned with a value of the type '" + queryAttrType.getName() + "' of the query attribute '" + modificationQueryAttribute + "'!");
}
if (returningAttributeBindingMap.put(cteAttribute, modificationQueryAttribute) != null) {
throw new IllegalArgumentException("The cte attribute [" + cteAttribute + "] has already been bound!");
}
for (String column : attributeEntry.getColumnNames()) {
if (columnBindingMap.put(column, cteAttribute) != null) {
throw new IllegalArgumentException("The cte column [" + column + "] has already been bound!");
}
}
return (X) this;
}
use of com.blazebit.persistence.spi.ExtendedAttribute in project blaze-persistence by Blazebit.
the class AbstractUpdateCollectionCriteriaBuilder method addAttribute.
@Override
protected void addAttribute(String attributeName) {
if (attributeName.equalsIgnoreCase(keyFunctionExpression)) {
Integer attributeBindIndex = setAttributeBindingMap.get(attributeName);
if (attributeBindIndex != null) {
throw new IllegalArgumentException("The attribute [" + attributeName + "] has already been bound!");
}
setAttributeBindingMap.put(attributeName, selectManager.getSelectInfos().size());
return;
}
ExtendedAttribute attributeEntry = collectionAttributeEntries.get(attributeName);
if (attributeEntry == null) {
Set<String> set = new TreeSet<>(collectionAttributeEntries.keySet());
if (keyFunctionExpression != null) {
set.add(keyFunctionExpression);
}
throw new IllegalArgumentException("The attribute [" + attributeName + "] does not exist or can't be bound! Allowed attributes are: " + set);
}
Integer attributeBindIndex = setAttributeBindingMap.get(attributeName);
if (attributeBindIndex != null) {
throw new IllegalArgumentException("The attribute [" + attributeName + "] has already been bound!");
}
setAttributeBindingMap.put(attributeName, selectManager.getSelectInfos().size());
}
use of com.blazebit.persistence.spi.ExtendedAttribute in project blaze-persistence by Blazebit.
the class CachingJpaProvider method hasJoinCondition.
@Override
public boolean hasJoinCondition(ManagedType<?> ownerType, String elementCollectionPath, String attributeName) {
ExtendedManagedType managedType = entityMetamodel.getManagedType(ExtendedManagedType.class, ownerType);
ExtendedAttribute attribute = (ExtendedAttribute) managedType.getAttributes().get(attributeName);
return attribute != null && attribute.hasJoinCondition();
}
use of com.blazebit.persistence.spi.ExtendedAttribute in project blaze-persistence by Blazebit.
the class CachingJpaProvider method isOrphanRemoval.
@Override
public boolean isOrphanRemoval(ManagedType<?> ownerType, String attributeName) {
ExtendedManagedType managedType = entityMetamodel.getManagedType(ExtendedManagedType.class, ownerType);
ExtendedAttribute attribute = (ExtendedAttribute) managedType.getAttributes().get(attributeName);
return attribute != null && attribute.isOrphanRemoval();
}
Aggregations