micronaut-jpa只更新非空字段

micronaut 原生的情况

更新所有值不管是否为null

笔者接口实现逻辑

将数据库中的值查出 ,将非空值覆盖到数据库中查出的值上,最后调用update接口

代码

import io.micronaut.aop.MethodInvocationContext;
import io.micronaut.aop.chain.MethodInterceptorChain;
import io.micronaut.core.annotation.Internal;
import io.micronaut.data.intercept.RepositoryMethodKey;
import io.micronaut.data.intercept.UpdateEntityInterceptor;
import io.micronaut.data.jpa.operations.JpaRepositoryOperations;
import io.micronaut.data.operations.RepositoryOperations;
import io.micronaut.data.repository.CrudRepository;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import javax.persistence.EntityManager;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;

/**
 * @author fuchanghai
 */
@Internal
public class UpdateService implements UpdateEntityInterceptor {

    private final JpaRepositoryOperations jpaOperations;

    protected UpdateService(RepositoryOperations operations) {
        if (operations instanceof JpaRepositoryOperations) {
            this.jpaOperations = (JpaRepositoryOperations) operations;
        } else {
            throw new IllegalStateException("Repository operations must be na instance of JpaRepositoryOperations");
        }
    }


    @Override

    public Object intercept(RepositoryMethodKey methodKey, MethodInvocationContext context) {
        MethodInterceptorChain chain = (MethodInterceptorChain) context;
        Object[] parameterValues = chain.getParameterValues();
        for (int i = 0; i < parameterValues.length; i++) {
            if (chain.getTarget() instanceof CrudRepository) {
                try {
                //此处可改进根据自定义注解获取id值
                    Field id = parameterValues[i].getClass().getDeclaredField("id");
                    id.setAccessible(true);
                    Optional byId = ((CrudRepository) chain.getTarget()).findById(id.get(parameterValues[i]));
                    String[] nullProperties = getNullProperties(parameterValues[i]);
                    Object target = byId.get();
                    BeanUtils.copyProperties(parameterValues[i], target, nullProperties);
                    EntityManager entityManager = jpaOperations.getCurrentEntityManager();
                    entityManager.merge(target);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }
        }
        return chain;
    }

    private static String[] getNullProperties(Object src) {
        BeanWrapper srcBean = new BeanWrapperImpl(src);
        PropertyDescriptor[] pds = srcBean.getPropertyDescriptors();
        Set<String> properties = new HashSet();
        PropertyDescriptor[] var4 = pds;
        int var5 = pds.length;

        for (int var6 = 0; var6 < var5; ++var6) {
            PropertyDescriptor propertyDescriptor = var4[var6];
            String propertyName = propertyDescriptor.getName();
            Object propertyValue = srcBean.getPropertyValue(propertyName);
            if (null == propertyValue) {
                srcBean.setPropertyValue(propertyName, (Object) null);
                properties.add(propertyName);
            }
        }

        return (String[]) properties.toArray(new String[0]);
    }

}



解决问题经过

1.刚开始在国内搜 搜不到
2.在国外网站以及stack overflow上也没找到
3.对照着spring-jpa的尿性绝对有个默认实现类,去github 上找到对应的接口,发现了UpdateEntityInterceptor 这个接口
4,@Inject EntityManager 发现是null
5迫不得已
在这里插入图片描述
6.作者给例子

在这里插入图片描述
在这里插入图片描述
当时是12 天前才写的那个例子,怪不得网上搜不到,
7最终 上面的那个类才自己实现了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值