hibernate实现数据实体复制保存
2013-12-16 11:57
330 查看
描述:需要将数据的一条记录进行复制保存为一条新记录。
思路:从数据库中取得一条记录封装到对象中,然后改变此对象的主键,保存此对象即可。
分析:看起来很简单快捷吧,但事实并非如此,执行出错“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一个对象一样,但是简单了很多,代码如下:
思路:从数据库中取得一条记录封装到对象中,然后改变此对象的主键,保存此对象即可。
分析:看起来很简单快捷吧,但事实并非如此,执行出错“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一个对象一样,但是简单了很多,代码如下:
public class CopyHandle extends LoggerBase { private static CopyHandle instance = null; private CopyHandle(){} public static CopyHandle getInstance(){ if(null == instance){ instance = new CopyHandle(); } return instance; } public Object copy(Object object) { Object objectCopy = null; try { 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 }); } } } catch (NoSuchMethodException e) { // TODO: handle exception this.logger.error("CopyHandle.copy(): NoSuchMethodException: "+ e); } catch (Exception e) { // TODO: handle exception this.logger.error("CopyHandle.copy(): Exception: "+ e); }finally{ return objectCopy; } } }
相关文章推荐
- hibernate实现数据实体复制保存
- 使用Myeclipse10.0自动生成搭建SSH框架(数据库表自动反向转换成Hibernate实体)实现用户登陆
- Spring3.x 整合hibernate 实现数据保存
- 使用Myeclipse10.0自动生成搭建SSH框架(数据库表自动反向转换成Hibernate实体)实现用户登陆
- Hibernate的自定义数据类型实现接口——UserType详解
- [AS3]URLLoader+URLRequest+JPGEncoder实现BitmapData图片数据保存
- 《EasyUI + MVC + EF +WCF》——实现对Datagrid中数据的批量修改或保存
- VS 2013下实现通过数据实体模型使用MySql
- 数据库间复制数据 非DTS程序实现
- 利用Oracle utl_tcp包实现数据实时复制
- Hibernate 先get 一个实体数据,在修改数据,为新的数据,再add到数据库,需要注意什么?
- Hibernate实现one-to-one级联保存
- 3DFDTD场值取样与探测取样的数据取样保存实现
- [导入]Ajax 实现在WebForm中拖动控件并即时在服务端保存状态数据 (Asp.net 2.0)(示例代码下载)
- C#:简单实现动态数据生成Word文档并保存
- Android实现动态切换横竖屏,保存横竖屏数据(用Preference存储)
- 【JavaScript】实现将从Excel中复制的数据粘贴到WEB页面Grid中
- 用JAVA实现将execl表格中多行数据复制粘贴到现有页面上(js控制)
- 妹子图APP(四)—— SQLite保存数据实现离线图片查看
- hibernate save没有保存数据到数据库