DATACMNS-293 - Further refinements in soft delete support.
Improved the template methods in AbstractSoftDeleteQueryAugmentor to accommodate more complex scenarios (see DATAJPA-307). Added DirectFieldAccessFallbackBeanWrapper from SD JPA to use it for looking up property values.
This commit is contained in:
committed by
Oliver Gierke
parent
2550c15166
commit
9c9904686b
@@ -15,16 +15,14 @@
|
||||
*/
|
||||
package org.springframework.data.repository.augment;
|
||||
|
||||
import org.springframework.beans.ConfigurablePropertyAccessor;
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.PropertyAccessor;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.data.repository.SoftDelete;
|
||||
import org.springframework.validation.DataBinder;
|
||||
import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;
|
||||
|
||||
/**
|
||||
* Base class to implement a {@link QueryAugmentor} to soft-delete entities.
|
||||
*
|
||||
* @since 1.6
|
||||
* @since 1.7
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public abstract class AbstractSoftDeleteQueryAugmentor<Q extends QueryContext<?>, N extends QueryContext<?>, U extends UpdateContext<?>>
|
||||
@@ -48,26 +46,32 @@ public abstract class AbstractSoftDeleteQueryAugmentor<Q extends QueryContext<?>
|
||||
return context;
|
||||
}
|
||||
|
||||
CustomDataBinder binder = new CustomDataBinder(entity);
|
||||
binder.initDirectFieldAccess();
|
||||
BeanWrapper wrapper = createBeanWrapper(context);
|
||||
|
||||
Object currentValue = binder.getPropertyAccessor().getPropertyValue(property);
|
||||
Object currentValue = wrapper.getPropertyValue(property);
|
||||
Object nextValue = annotation.flagMode().toDeletedValue(currentValue);
|
||||
|
||||
if (nextValue == null) {
|
||||
return context;
|
||||
}
|
||||
|
||||
MutablePropertyValues values = new MutablePropertyValues();
|
||||
values.add(property, nextValue);
|
||||
|
||||
binder.bind(values);
|
||||
|
||||
wrapper.setPropertyValue(property, nextValue);
|
||||
updateDeletedState(entity, context);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link BeanWrapper} for the given {@link UpdateContext}. Defaults to a
|
||||
* {@link DirectFieldAccessFallbackBeanWrapper}.
|
||||
*
|
||||
* @param context will never be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
protected BeanWrapper createBeanWrapper(U context) {
|
||||
return new DirectFieldAccessFallbackBeanWrapper(context.getEntity());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the entity using the API exposed in the given {@link UpdateContext}.
|
||||
*
|
||||
@@ -75,21 +79,4 @@ public abstract class AbstractSoftDeleteQueryAugmentor<Q extends QueryContext<?>
|
||||
* @param context will never be {@literal null}.
|
||||
*/
|
||||
public abstract void updateDeletedState(Object entity, U context);
|
||||
|
||||
/**
|
||||
* Custom {@link DataBinder} to expose the {@link PropertyAccessor} used.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class CustomDataBinder extends DataBinder {
|
||||
|
||||
public CustomDataBinder(Object target) {
|
||||
super(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigurablePropertyAccessor getPropertyAccessor() {
|
||||
return super.getPropertyAccessor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,13 +109,17 @@ public abstract class AnnotationBasedQueryAugmentor<T extends Annotation, Q exte
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.augment.QueryAugmentor#augmentNativeQuery(org.springframework.data.repository.augment.QueryContext, org.springframework.data.repository.augment.MethodMetadata)
|
||||
*/
|
||||
public final N augmentNativeQuery(N context, MethodMetadata metadata) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jpa.repository.support.JpaQueryAugmentor#augmentQuery(javax.persistence.criteria.CriteriaQuery, org.springframework.data.repository.core.support.MethodMetadata)
|
||||
* @see org.springframework.data.repository.augment.QueryAugmentor#augmentQuery(org.springframework.data.repository.augment.QueryContext, org.springframework.data.repository.augment.MethodMetadata)
|
||||
*/
|
||||
public final Q augmentQuery(Q context, MethodMetadata metadata) {
|
||||
|
||||
@@ -129,9 +133,9 @@ public abstract class AnnotationBasedQueryAugmentor<T extends Annotation, Q exte
|
||||
return expression == null ? context : prepareQuery(context, expression);
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.QueryAugmentor#augmentUpdate(org.springframework.data.repository.core.support.UpdateContext, org.springframework.data.repository.core.support.MethodMetadata)
|
||||
* @see org.springframework.data.repository.augment.QueryAugmentor#augmentUpdate(org.springframework.data.repository.augment.UpdateContext, org.springframework.data.repository.augment.MethodMetadata)
|
||||
*/
|
||||
public final U augmentUpdate(U update, MethodMetadata metadata) {
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.aop.ProxyMethodInvocation;
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.framework.ReflectiveMethodInvocation;
|
||||
@@ -636,6 +637,7 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware {
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryProxyPostProcessor#postProcess(org.springframework.aop.framework.ProxyFactory, org.springframework.data.repository.core.RepositoryInformation)
|
||||
*/
|
||||
@Override
|
||||
public void postProcess(ProxyFactory factory, RepositoryInformation repositoryInformation) {
|
||||
factory.addAdvice(ExposeInvocationInterceptor.INSTANCE);
|
||||
}
|
||||
@@ -664,7 +666,7 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware {
|
||||
|
||||
if (invocation instanceof ReflectiveMethodInvocation) {
|
||||
Advised proxy = (Advised) ((ReflectiveMethodInvocation) invocation).getProxy();
|
||||
return Arrays.asList((Class<?>[]) proxy.getProxiedInterfaces());
|
||||
return Arrays.asList(proxy.getProxiedInterfaces());
|
||||
}
|
||||
|
||||
return Collections.<Class<?>> singletonList(getMethodInvocation().getThis().getClass());
|
||||
|
||||
Reference in New Issue
Block a user