java代码用目标对象替换源对象的值(针对相同对象之间的替换)

前言:今天测试提了一个优化,在表单提交审批的时候,验证一下表单正确性,在不符合条件的情况下alert出来,并不需要刷新页面(原先因为是从产品上改的项目,存在问题颇多,这个页面alert之后会刷新一遍),一看是这样的问题,我回他分分钟搞定。

          。。。。。。

          现在我的脸已经被打得很肿了,在我把刷新的js代码去掉之后,点击提交审批,弹出验证,关闭验证,页面没有刷新,“不错,不错,完美!!!”,内心比了个(金女士?先生?疑问)的手势,并顺手又点了一下提交,“嗯?”验证信息没有弹出来。。。emmmmm。。。可能是没点上,又点了一遍,还是没有。。。好吧,debug吧。

           然后开始了排查工作,F6一步一步摁着看,发现在保存表单信息的时候,第一次点击提交按钮不报错,第二次这会报

org.springframework.orm.hibernate4.HibernateOptimisticLockingFailureException

这样的错,没遇到过,看信息应该是hibernate的问题,只能问度娘了。

           百度的结果大体上是这三种:

1、由于主键设置为自增长,在我们插入记录的时候设置了Id的值,Hibernate的映射配置文件中,把id 的class改为assigned类型。

2、使用了hibernate的saveOrUpdata方法进行保存实例,saveOrUpdate要求:只有Id为null才能执行save,其他情况下执行update,在保存实例的时候是新增,但如果id不为null,所有的执行都是update操作,可是数据库没有主键对应的值,所以出现了异常,解决办法:unsaved-value="null"是否设置

3、在Hibernate映射一对多,多对一,多对多的时候新增常常会出现异常

java代码:下面的beanutils是apache包下的

public void saveFunctionCell(FunctionCell functionCell,Integer pid)(
  System.out.print("现在进行新增操作");
  FunctionCell fc = new FunctionCell();
  try{
     BeanUtils.copyProperties(fc,functionCell);
     fc.setFunCellID(null);
     functionCellDao.saveFunctionCell(fc);
  }catch(Exception e){
     e.printStackTrace();
  }
}

关键是beanutils的用法!!!!

注意特别标识出来的这个地方,BeanUtils拷贝Bean属性的时候,它会将你的Integer类型全部设置为0,在这里设置一个空null,这样就不会抛出错误了。


结论:结合上面这些可能性进行尝试,发现在id为null的情况下保存没有问题,可能的原因就是在执行保存的时候,前一次的保存事物影响了下面一次的保存,需要在id不为空的情况下重新new一个对象进行保存。


解决办法:

一看我需要保存的这个对象,一下子懵逼了,大致数数有100多个属性,这样一个一个的set值到什么时候,这时候就需要我们用目标对象替换源对象的值,直接把Object的值全部放到新new的Object中。

/**
     * 比较用目标对象替换源对象的值
     * @param source 源对象
     * @param target 目标对象
     * @return       最新源对象
     * @see
     */
    public static Object getObjectByCompareWith(Object source, Object target) {
        Class<?> srcClass = source.getClass();
        Field[] fields = srcClass.getDeclaredFields();
        for (Field field : fields) {
            String nameKey = field.getName();
            //获取源对象中的属性值
            String srcValue = getClassValue(source, nameKey) == null ? "" : getClassValue(source, nameKey).toString();
            //获取目标对象中的属性值
            String tarValue = getClassValue(target, nameKey) == null ? "" : getClassValue(target, nameKey).toString();
            //比较两个属性值,不相等的时候进行赋值
            if (!srcValue.equals(tarValue)) {
                source  = setClassValue(source, nameKey, tarValue);
            }
        }
        return source;
    }
/**
     * 根据字段名称取值
     * @param obj 指定对象
     * @param fieldName 字段名称
     * @return 指定对象
     */
    public static Object getClassValue(Object obj, String fieldName) {
        if (obj == null) {
            return null;
        }
        Class beanClass = obj.getClass();
        Method[] ms = beanClass.getMethods();
        for (int i = 0; i < ms.length; i++ ) {
            // 非get方法不取
            if (!ms[i].getName().startsWith("get")) {
                continue;
            }
            Object objValue = null;
            try {
                objValue = ms[i].invoke(obj, new Object[] {});
            } catch (Exception e) {
                continue;
            }
            if (objValue == null) {
                continue;
            }
            if (ms[i].getName().toUpperCase().equals(fieldName.toUpperCase())
                || ms[i].getName().substring(3).toUpperCase().equals(fieldName.toUpperCase())) {
                return objValue;
            }
        }
        return null;
    }
/**
     * 给对象的字段赋指定的值
     * @param obj       指定对象
     * @param fieldName 属性
     * @param value     值
     * @return 
     * @see
     */
    public static Object setClassValue(Object obj, String fieldName, Object value) {
       if (obj == null) {
            return null;
        }
       if(Constant.STRING_NULL.equals(value)) {
           value = null;
       }
       Class beanClass = obj.getClass();
       Method[] ms = beanClass.getMethods();
       for (int i = 0; i < ms.length; i++) {
           try {
               if (ms[i].getName().startsWith("set")) {
                   if(ms[i].getName().toUpperCase().equals(fieldName.toUpperCase())
                       || ms[i].getName().substring(3).toUpperCase().equals(fieldName.toUpperCase())) {
                       String pt = ms[i].getParameterTypes()[0].toString();
                       if(value != null) {
                           ms[i].invoke(obj, transVal(value.toString(), pt.substring(pt.lastIndexOf(".")+1)));
                       } else {
                           ms[i].invoke(obj, new Object[]{null});
                       }
                       break;
                   }
               }
           } catch (Exception e) {
               continue;
           }
       }
       return obj;
   }
/**
     * 根据属性类型赋值
     * @param value      值
     * @param paramsType 属性类型
     * @return 
     * @see
     */
    public static Object transVal(String value, String paramsType) {
        if(ColumnType.String.toString().equals(paramsType)) {
            return new String(value);
        }
        if(ColumnType.Double.toString().equals(paramsType)) {
            return Double.parseDouble(value);
        }
        if(ColumnType.Integer.toString().equals(paramsType)) {
            return Integer.parseInt(value);
        }
        if(ColumnType.Long.toString().equals(paramsType)) {
            return Long.parseLong(value);
        }    
        if(ColumnType.BigDecimal.toString().equals(paramsType)) {
            return new BigDecimal(value);
        }        
        return value;
    }
package com.xxx.utils;

/**
 * <简述> 定义类型枚举
 * <详细描述>
 * @author   xxx
 * @version  $Id$
 * @since
 * @see
 */
public enum ColumnType {
    String, Double, Integer, Long, BigDecimal;
}
直接调用方法
xxxNew = (Xxx)ObjectCompareUtils.getObjectByCompareWith(xxxNew, xxx);

即可把源对象的值替换成目标对象的值。

这样再提交保存该表单,完美执行,每次点击都能出现验证信息。

finish!!!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值