PATCH接口中BeanUtilsBean copyProperties无法设置属性为null的问题
使用Apache Commons BeanUtilsBean的copyProperties无法将属性设为null的问题排查
问题背景
我在实现一个PATCH接口的更新流程时,遇到了BeanUtilsBean的copyProperties方法无法将目标对象的属性设置为null的问题。
接口代码:
@Path("/calendrier-serveur") @PATCH @Produces(MediaType.APPLICATION_JSON) public Response updateCalendrierServeur(TPosCalendrierServeur data) { try { TPosCalendrierServeur newData = service.updateCalendrierServeur(data); return Response.ok(newData, MediaType.APPLICATION_JSON).build(); } catch (IllegalAccessException | InvocationTargetException e) { LOGGER.error("Error occured while updating server calendar." + e.getStackTrace()); Payload payload = new Payload("Invalid payload.",e.getMessage()); return Response.status(Response.Status.BAD_REQUEST).entity(payload).build(); } }
服务层代码:
... import org.apache.commons.beanutils.BeanUtilsBean; ... @Transactional public TPosCalendrierServeur updateCalendrierServeur(TPosCalendrierServeur data) throws IllegalAccessException, InvocationTargetException { TPosCalendrierServeur original = calendrierServeurRepository.find("mmcUserId = ?1", data.getMmcUserId()).firstResult(); BeanUtilsBean beanUtil = new NullAwareBeanUtilsBean(); beanUtil.copyProperties(original, data); calendrierServeurRepository.getEntityManager().merge(original); original = calendrierServeurRepository.find("mmcUserId = ?1", data.getMmcUserId()).firstResult(); return original; }
调试发现:调用服务时,执行copyProperties前data.getAbsenceDebut()的值为null,但执行后original对象的该属性仍然保留数据库中的原始值,无法被设置为null。
问题原因
你使用的NullAwareBeanUtilsBean是自定义工具类,这类实现的核心逻辑通常是跳过源对象中值为null的属性,不会将null值复制到目标对象上。这种设计多用于避免覆盖目标对象的非空属性,但恰好与PATCH请求中需要主动将属性置为null的需求冲突。
解决办法
使用原生
BeanUtilsBean:如果不需要跳过null值的逻辑,直接实例化默认的BeanUtilsBean即可,它会将源对象的null值同步到目标对象:BeanUtilsBean beanUtil = new BeanUtilsBean(); beanUtil.copyProperties(original, data);修改自定义
NullAwareBeanUtilsBean的逻辑:如果需要区分“属性未传入”和“属性明确设为null”(适配PATCH场景),可以调整copyProperty方法,允许null值被复制:public class NullAwareBeanUtilsBean extends BeanUtilsBean { @Override public void copyProperty(Object dest, String name, Object value) throws IllegalAccessException, InvocationTargetException { // 取消跳过null的判断,直接执行复制 super.copyProperty(dest, name, value); } }或者添加条件判断,比如仅当属性是主动设置为null时才复制,根据业务需求灵活调整。
更换对象映射工具:如果Apache Commons BeanUtils的灵活性不足,可以考虑使用ModelMapper、MapStruct这类工具,它们提供了更细致的null值处理配置,更适合RESTful的PATCH更新场景。
内容的提问来源于stack exchange,提问作者pheromix
相关产品推荐
相关产品推荐

