use of com.blazebit.persistence.view.impl.EntityViewManagerImpl in project blaze-persistence by Blazebit.
the class ViewMapper method createAccessor.
private ObjectMapper createAccessor(ManagedViewType<S> sourceType, ManagedViewType<T> targetType, boolean ignoreMissing, EntityViewKindMapping entityViewKindMapping, EntityViewManager entityViewManager, ProxyFactory proxyFactory, MethodAttribute<? super T, ?> targetAttribute, String prefix, Map<String, Key<Object, Object>> subMappers) {
String newPrefix;
if (prefix.isEmpty()) {
newPrefix = targetAttribute.getName();
} else {
newPrefix = prefix + "." + targetAttribute.getName();
}
Type<?> attributeType;
MappingConstructorImpl<?> constructor = null;
Boolean maybeMarkNew = entityViewKindMapping == EntityViewKindMapping.MARK_NEW ? null : false;
Key<Object, Object> subMapperKey = subMappers.get(newPrefix);
if (subMapperKey == Key.EXCLUDE_MARKER) {
return null;
} else if (subMapperKey != null) {
ignoreMissing = subMapperKey.ignoreMissing;
maybeMarkNew = subMapperKey.markNew;
}
// Try to find a source attribute
MethodAttribute<?, ?> sourceAttribute;
AttributeAccessor accessor;
if (sourceType == null) {
sourceAttribute = null;
if (targetAttribute.getMappingType() == Attribute.MappingType.PARAMETER) {
return new ParameterObjectMapper(((MappingAttribute<?, ?>) targetAttribute).getMapping());
}
accessor = Accessors.forEntityMapping((EntityViewManagerImpl) entityViewManager, targetAttribute);
if (accessor == null) {
if (ignoreMissing) {
return null;
}
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type is missing in source type!", targetType);
}
} else {
sourceAttribute = sourceType.getAttribute(targetAttribute.getName());
if (sourceAttribute == null) {
if (targetAttribute.getMappingType() == Attribute.MappingType.PARAMETER) {
return new ParameterObjectMapper(((MappingAttribute<?, ?>) targetAttribute).getMapping());
}
// Optionally ignore missing attributes
if (ignoreMissing) {
return null;
}
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type is missing in source type!", sourceType, targetType);
}
accessor = Accessors.forViewAttribute(null, sourceAttribute, true);
}
// Handle conversion from one type to another
if (targetAttribute.isCollection()) {
if ((sourceAttribute != null) && (targetAttribute.getConvertedJavaType() != sourceAttribute.getConvertedJavaType())) {
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different plural type than in source type!", sourceType, targetType);
}
PluralAttribute<?, ?, ?> targetPluralAttr = (PluralAttribute<?, ?, ?>) targetAttribute;
Type<?> elementType = (sourceAttribute == null) ? null : ((PluralAttribute<?, ?, ?>) sourceAttribute).getElementType();
ViewMapper<Object, Object> valueMapper = null;
attributeType = targetPluralAttr.getElementType();
if (subMapperKey != null) {
attributeType = subMapperKey.targetType;
constructor = subMapperKey.targetConstructor;
}
if (targetAttribute.isSubview()) {
valueMapper = createViewMapper(elementType, attributeType, constructor, ignoreMissing, maybeMarkNew, entityViewManager, proxyFactory, newPrefix, subMappers);
} else if ((sourceType != null) && (targetPluralAttr.getElementType() != elementType)) {
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different element type than in source type!", sourceType, targetType);
}
boolean needsDirtyTracker = ((AbstractAttribute<?, ?>) targetAttribute).needsDirtyTracker();
if (targetPluralAttr.getCollectionType() == PluralAttribute.CollectionType.MAP) {
MapAttribute<?, ?, ?> targetMapAttr = (MapAttribute<?, ?, ?>) targetAttribute;
Type<?> keyType = (sourceAttribute == null) ? null : ((MapAttribute<?, ?, ?>) sourceAttribute).getKeyType();
ViewMapper<Object, Object> keyMapper = null;
if (targetMapAttr.isKeySubview()) {
String newKeyPrefix = "KEY(" + newPrefix + ")";
Key<Object, Object> keySubMapperKey = subMappers.get(newKeyPrefix);
if (keySubMapperKey == Key.EXCLUDE_MARKER) {
keyMapper = null;
} else {
constructor = null;
Type<?> keyTargetType = targetMapAttr.getKeyType();
Boolean maybeMarkNewKey = entityViewKindMapping == EntityViewKindMapping.MARK_NEW ? null : false;
if (subMapperKey != null) {
constructor = keySubMapperKey.targetConstructor;
keyTargetType = keySubMapperKey.targetType;
ignoreMissing = keySubMapperKey.ignoreMissing;
maybeMarkNewKey = keySubMapperKey.markNew;
}
keyMapper = createViewMapper(keyType, keyTargetType, constructor, ignoreMissing, maybeMarkNewKey, entityViewManager, proxyFactory, newPrefix, subMappers);
}
} else if ((sourceType != null) && (targetMapAttr.getKeyType() != keyType)) {
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different key type than in source type!", sourceType, targetType);
}
MapInstantiatorImplementor<?, ?> mapInstantiator = ((AbstractAttribute<?, ?>) targetAttribute).getMapInstantiator();
return new MapObjectMapper(accessor, needsDirtyTracker, entityViewKindMapping != EntityViewKindMapping.MARK_NEW, mapInstantiator, keyMapper, valueMapper);
} else {
CollectionInstantiatorImplementor<?, ?> collectionInstantiator = ((AbstractAttribute<?, ?>) targetAttribute).getCollectionInstantiator();
return new CollectionObjectMapper(accessor, needsDirtyTracker, entityViewKindMapping != EntityViewKindMapping.MARK_NEW, collectionInstantiator, valueMapper);
}
} else if (targetAttribute.isSubview()) {
attributeType = ((SingularAttribute<?, ?>) targetAttribute).getType();
if (subMapperKey != null) {
attributeType = subMapperKey.targetType;
constructor = subMapperKey.targetConstructor;
}
Type<?> type = (sourceAttribute == null) ? null : ((SingularAttribute<?, ?>) sourceAttribute).getType();
ViewMapper<Object, Object> mapper = createViewMapper(type, attributeType, constructor, ignoreMissing, maybeMarkNew, entityViewManager, proxyFactory, newPrefix, subMappers);
return new AttributeObjectMapper(accessor, mapper);
} else if ((sourceAttribute != null) && (targetAttribute.getConvertedJavaType() != sourceAttribute.getConvertedJavaType())) {
throw inconvertible("Attribute '" + targetAttribute.getName() + "' from target type has a different type than in source type!", sourceType, targetType);
} else {
return new PassthroughObjectMapper(accessor);
}
}
use of com.blazebit.persistence.view.impl.EntityViewManagerImpl in project blaze-persistence by Blazebit.
the class InverseFlusher method removeByOwnerId.
public List<PostFlushDeleter> removeByOwnerId(UpdateContext context, Object ownerId) {
EntityViewManagerImpl evm = context.getEntityViewManager();
CriteriaBuilder<Object> cb = (CriteriaBuilder<Object>) evm.getCriteriaBuilderFactory().create(context.getEntityManager(), parentEntityClass, "e").where(parentIdAttributeName).eq(ownerId).where("e." + attributeName + "." + childIdAttributeName).isNotNull();
if (childIdViewClass == null) {
cb.select("e." + attributeName + "." + childIdAttributeName);
} else {
evm.applySetting(EntityViewSetting.create(childIdViewClass), cb, "e." + attributeName + "." + childIdAttributeName);
}
List<Object> elementIds = cb.getResultList();
if (!elementIds.isEmpty()) {
// We must always delete this, otherwise we might get a constraint violation because of the cascading delete
removeByOwnerIdOnly(context, ownerId);
}
return Collections.<PostFlushDeleter>singletonList(new PostFlushInverseCollectionElementByIdDeleter(deleter, elementIds));
}
use of com.blazebit.persistence.view.impl.EntityViewManagerImpl in project blaze-persistence by Blazebit.
the class MapAttributeFlusher method removeByOwnerId.
private List<PostFlushDeleter> removeByOwnerId(UpdateContext context, Object ownerId, boolean cascade) {
EntityViewManagerImpl evm = context.getEntityViewManager();
if (cascade) {
List<Object> elementIds;
// If there is no inverseFlusher/mapped by attribute, the collection has a join table
if (evm.getDbmsDialect().supportsReturningColumns()) {
List<Tuple> tuples = evm.getCriteriaBuilderFactory().deleteCollection(context.getEntityManager(), ownerEntityClass, "e", mapping).where(ownerIdAttributeName).eq(ownerId).executeWithReturning(mapping + "." + elementDescriptor.getAttributeIdAttributeName()).getResultList();
elementIds = new ArrayList<>(tuples.size());
for (Tuple tuple : tuples) {
elementIds.add(tuple.get(0));
}
} else {
elementIds = (List<Object>) evm.getCriteriaBuilderFactory().create(context.getEntityManager(), ownerEntityClass, "e").where(ownerIdAttributeName).eq(ownerId).select("e." + mapping + "." + elementDescriptor.getAttributeIdAttributeName()).getResultList();
if (!elementIds.isEmpty() && !jpaProviderDeletesCollection) {
// We must always delete this, otherwise we might get a constraint violation because of the cascading delete
DeleteCriteriaBuilder<?> cb = evm.getCriteriaBuilderFactory().deleteCollection(context.getEntityManager(), ownerEntityClass, "e", mapping);
cb.where(ownerIdAttributeName).eq(ownerId);
cb.executeUpdate();
}
}
return Collections.<PostFlushDeleter>singletonList(new PostFlushCollectionElementByIdDeleter(elementDescriptor.getElementToEntityMapper(), elementIds));
} else if (!jpaProviderDeletesCollection) {
// delete from Entity(collectionRole) e where e.id = :id
DeleteCriteriaBuilder<?> cb = evm.getCriteriaBuilderFactory().deleteCollection(context.getEntityManager(), ownerEntityClass, "e", mapping);
cb.where("e." + ownerIdAttributeName).eq(ownerId);
cb.executeUpdate();
}
return Collections.emptyList();
}
use of com.blazebit.persistence.view.impl.EntityViewManagerImpl in project blaze-persistence by Blazebit.
the class UnmappedCollectionAttributeCascadeDeleter method removeByOwnerId.
@Override
public void removeByOwnerId(UpdateContext context, Object ownerId) {
EntityViewManagerImpl evm = context.getEntityViewManager();
if (cascadeDeleteElement) {
List<Object> elementIds;
if (mappedByAttributeName == null) {
// If there is no mapped by attribute, the collection has a join table
if (evm.getDbmsDialect().supportsReturningColumns()) {
List<Tuple> tuples = evm.getCriteriaBuilderFactory().deleteCollection(context.getEntityManager(), ownerEntityClass, "e", attributeName).where(ownerIdAttributeName).eq(ownerId).executeWithReturning(attributeName + "." + elementIdAttributeName).getResultList();
elementIds = new ArrayList<>(tuples.size());
for (Tuple tuple : tuples) {
elementIds.add(tuple.get(0));
}
} else {
elementIds = (List<Object>) evm.getCriteriaBuilderFactory().create(context.getEntityManager(), ownerEntityClass, "e").where(ownerIdAttributeName).eq(ownerId).select("e." + attributeName + "." + elementIdAttributeName).getResultList();
if (!elementIds.isEmpty()) {
// We must always delete this, otherwise we might get a constraint violation because of the cascading delete
DeleteCriteriaBuilder<?> cb = evm.getCriteriaBuilderFactory().deleteCollection(context.getEntityManager(), ownerEntityClass, "e", attributeName);
cb.where(ownerIdAttributeName).eq(ownerId);
cb.executeUpdate();
}
}
for (Object elementId : elementIds) {
elementDeleter.removeById(context, elementId);
}
} else {
// Since there is a mapped by attribute, there is no join table to clear. Just delete the element by the owner id
elementDeleter.removeByOwnerId(context, ownerId);
}
} else if (!jpaProviderDeletesCollection) {
DeleteCriteriaBuilder<?> cb = evm.getCriteriaBuilderFactory().deleteCollection(context.getEntityManager(), ownerEntityClass, "e", attributeName);
cb.where(ownerIdAttributeName).eq(ownerId);
cb.executeUpdate();
}
}
use of com.blazebit.persistence.view.impl.EntityViewManagerImpl in project blaze-persistence by Blazebit.
the class CollectionAttributeFlusher method removeByOwnerId.
private List<PostFlushDeleter> removeByOwnerId(UpdateContext context, Object ownerId, boolean cascade) {
EntityViewManagerImpl evm = context.getEntityViewManager();
String mapping = getMapping();
if (cascade) {
List<Object> elementIds;
if (inverseFlusher == null) {
// If there is no inverseFlusher/mapped by attribute, the collection has a join table
if (evm.getDbmsDialect().supportsReturningColumns()) {
List<Tuple> tuples = evm.getCriteriaBuilderFactory().deleteCollection(context.getEntityManager(), ownerEntityClass, "e", mapping).where(ownerIdAttributeName).eq(ownerId).executeWithReturning(mapping + "." + elementDescriptor.getAttributeIdAttributeName()).getResultList();
elementIds = new ArrayList<>(tuples.size());
for (Tuple tuple : tuples) {
elementIds.add(tuple.get(0));
}
} else {
elementIds = (List<Object>) evm.getCriteriaBuilderFactory().create(context.getEntityManager(), ownerEntityClass, "e").where(ownerIdAttributeName).eq(ownerId).where("e." + mapping + "." + elementDescriptor.getAttributeIdAttributeName()).isNotNull().select("e." + mapping + "." + elementDescriptor.getAttributeIdAttributeName()).getResultList();
if (!elementIds.isEmpty() && !jpaProviderDeletesCollection) {
// We must always delete this, otherwise we might get a constraint violation because of the cascading delete
DeleteCriteriaBuilder<?> cb = evm.getCriteriaBuilderFactory().deleteCollection(context.getEntityManager(), ownerEntityClass, "e", mapping);
cb.where(ownerIdAttributeName).eq(ownerId);
cb.executeUpdate();
}
}
return Collections.<PostFlushDeleter>singletonList(new PostFlushCollectionElementByIdDeleter(elementDescriptor.getElementToEntityMapper(), elementIds));
} else {
return inverseFlusher.removeByOwnerId(context, ownerId);
}
} else if (!jpaProviderDeletesCollection) {
// delete from Entity(collectionRole) e where e.id = :id
DeleteCriteriaBuilder<?> cb = evm.getCriteriaBuilderFactory().deleteCollection(context.getEntityManager(), ownerEntityClass, "e", mapping);
cb.where(ownerIdAttributeName).eq(ownerId);
cb.executeUpdate();
}
return Collections.emptyList();
}
Aggregations