import java.io.Serializable;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.example.demo.jobs.CustomQueryParamMethodInterceptor;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import org.springframework.data.repository.core.support.RepositoryProxyPostProcessor;
import org.springframework.data.repository.core.support.TransactionalRepositoryFactoryBeanSupport;
import org.springframework.util.Assert;
public class MyJpaRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> {
private EntityManager entityManager;
private static final CustomQueryParamMethodInterceptor interceptor = new CustomQueryParamMethodInterceptor();
/**
* Creates a new {@link JpaRepositoryFactoryBean} for the given repository interface.
*
* @param repositoryInterface must not be {@literal null}.
*/
public MyJpaRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
super(repositoryInterface);
}
/**
* The {@link EntityManager} to be used.
*
* @param entityManager the entityManager to set
*/
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
/*
* (non-Javadoc)
* @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#setMappingContext(org.springframework.data.mapping.context.MappingContext)
*/
@Override
public void setMappingContext(MappingContext<?, ?> mappingContext) {
super.setMappingContext(mappingContext);
}
/*
* (non-Javadoc)
*
* @see org.springframework.data.repository.support.
* TransactionalRepositoryFactoryBeanSupport#doCreateRepositoryFactory()
*/
@Override
protected RepositoryFactorySupport doCreateRepositoryFactory() {
RepositoryFactorySupport support = createRepositoryFactory(entityManager);
support.addRepositoryProxyPostProcessor(new RepositoryProxyPostProcessor() {
@Override
public void postProcess(ProxyFactory factory, RepositoryInformation repositoryInformation) {
factory.addAdvice(interceptor);
}
});
return support;
}
/**
* Returns a {@link RepositoryFactorySupport}.
*
* @param entityManager
* @return
*/
protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
return new JpaRepositoryFactory(entityManager);
}
/*
* (non-Javadoc)
*
* @see
* org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() {
Assert.notNull(entityManager, "EntityManager must not be null!");
super.afterPropertiesSet();
}
}
, а затем добавьте аннотацию к классу приложения Spring
@EnableJpaRepositories(repositoryFactoryBeanClass = MyJpaRepositoryFactoryBean.class)
и создайте метод-перехватчик для преобразования параметра Enum в определенный тип
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import com.example.demo.dto.ParamWrapper;
import com.example.demo.dto.StatusType;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
public class CustomQueryParamMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
if (invocation instanceof ReflectiveMethodInvocation) {
ReflectiveMethodInvocation rmi = (ReflectiveMethodInvocation)invocation;
Object[] args = invocation.getArguments();
if (args != null && args.length > 0) {
Object[] newArgs = new Object[args.length];
for (int i=0 ;i<args.length; i++) {
if (args[i] instanceof ParamWrapper) {
ParamWrapper p = (ParamWrapper)args[i];
newArgs[i] = p.getValue();
} else {
newArgs[i] = args[i];
}
}
rmi.setArguments(newArgs);
}
}
return invocation.proceed();
}
}
ParamWrapperявляется универсальным типом, который ваше перечисление должно реализовать
public interface ParamWrapper<T> {
T getValue();
}
, тогда ваше перечисление должно измениться следующим образом
public enum StatusType implements ParamWrapper<Integer> {
ACTIVE,
TO_BE_DELETED,
@Deprecated IN_ACTIVE;
@Override
public Integer getValue() {
//you should determine your value
return 1;
}
}