hibernate实现数据实体复制保存

描述:需要将数据的一条记录进行复制保存为一条新记录。

思路:从数据库中取得一条记录封装到对象中,然后改变此对象的主键,保存此对象即可。

   分析:看起来很简单快捷吧,但事实并非如此,执行出错“identifier of the object was alter from 1 to 10”,因为从数据库中取得的对象是持久化对象。在hibernate的缓存中有一个备份。当你修改了持久化对象,提交事务时,hibernate就会比较当前对象和在缓存中备份的对象,如果不一样则更新数据库。这里需要注意:更新是根据主键更新的:也就是 update tablename set ... where 主键=‘?’。 但是如果你把主键的值改了,hibernate在更新的时候就无法更新数据库了,所以就产生了上面的错误。

解决的办法有三种

解决办法一:evict(object) :在改变对象主键之前。利用evict方法清理hibernate缓存,此对象将不再是持久化对象,所以不会去更新数据库。成功。但是hibernate不提倡用此方法

解决办法二:重新new一个对象,把原来的对象的属性值一一set进来,然后保存。重新new的对象是瞬时对象,保存成功。但如果存在大量的属性,或者此表存在子表数量多,那么必须为每个表的对象都new一次,然后赋值。这将很耗时,非常讨厌。

解决办法三:利用java反射机制复制一个对象出来,效果的new一个对象一样,但是简单了很多(ps:java反射机制复制对象,到底能提高多少效率,值得商榷),代码如下:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method; 


    public class CopyObject {
    public static Object copy(Object object) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {  
       Object objectCopy = null; 
       if(null == object) return null;  
            Class<?> classType = object.getClass();        
            //取原对象的属性
            Field fields[] = classType.getDeclaredFields();
            //创建赋值对象
            objectCopy = classType.getConstructor(new Class[] {}).newInstance(new Object[] {});    
            Field field = null;  
            String suffixMethodName;  
            Method getMethod, setMethod;  
            Object value = null;  
            for(int i = 0; i < fields.length; i++) {  
                field = fields[i];  
                suffixMethodName = field.getName().substring(0, 1).toUpperCase() + (field.getName().length()>1?field.getName().substring(1):"");       
                getMethod = classType.getMethod("get" + suffixMethodName, new Class[] {});    
                setMethod = classType.getMethod("set" + suffixMethodName, new Class[] { field.getType() });  
                value = getMethod.invoke(object, new Object[] {});  
                if(null == value){  
                    if(field.getType().getName().equalsIgnoreCase("java.lang.String")){  
                        setMethod.invoke(objectCopy, new Object[] { "" });  
                    }  
                }else{  
                    setMethod.invoke(objectCopy, new Object[] { value });  
                }  
            }
            return objectCopy;   
    }
    }
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页