hibernate实现数据实体复制保存
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一个对象一样,但是简单了很多,代码如下:
- 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实现数据实体复制保存的更多相关文章
- Hibernate第二天——实体类 与缓存机制
第二天,我们先来了解一下框架里的一个重要概念:实体类 实体类:把数据表或其它持久化数据的格式映射成的类,就是实体类. 实体类的编写规则:由于对应的是javabean,因而也遵循javabean的一些规 ...
- Hibernate的数据查找,添加!
1.首先看一下测试数据库的物理模型 2.测试所需要的Hibernate的jar包 3.数据库的sql /*=============================================== ...
- Hibernate映射之实体映射<转载>
实体类与数据库之间存在某种映射关系,Hibernate依据这种映射关系完成数据的存取,因此映射关系的配置在Hibernate中是最关键的.Hibernate支持xml配置文件与@注解配置两种方式.xm ...
- hibernate中对象集合的保存
一.在java web设计中经常使用对象进行操作,在hibernate中对象集合的保存(一对多) 1需要进行如下步骤: 1) 设计数据表关系 2)引入jar包,需要注意引入数据库connector 3 ...
- oracle复制表数据,复制表结构
1.不同用户之间的表数据复制 2.同用户表之间的数据复制 3.B.x中个别字段转移到B.y的相同字段 4.只复制表结构 加入了一个永远不可能成立的条件1=2,则此时表示的是只复制表结构,但是不复制表内 ...
- Redis 小白指南(四)- 数据的持久化保存(草稿)
Redis 小白指南(四)- 数据的持久化保存 简介 因为 redis 将数据保存在内存中,很容易诱发的一个问题就是,程序崩溃或服务器重启等情况如何保证数据的正常存储. 当我们以 redis 作为主数 ...
- 在Intellij IDEA下通过Hibernate逆向生成实体类
前言:在IDEA中,通过相关插件,可以利用Hibernate逆向生成数据表对应的实体类.具体操作及注意事项见本篇随笔. 1.创建一个基于maven的hibernate工程.并在工程中添夹hiberna ...
- oracle 复制表数据,复制表结构
1.不同用户之间的表数据复制 对于在一个数据库上的两个用户A和B,假如需要把A下表old的数据复制到B下的new,请使用权限足够的用户登入sqlplus:insert into B.new(selec ...
- 【原】Learning Spark (Python版) 学习笔记(二)----键值对、数据读取与保存、共享特性
本来应该上周更新的,结果碰上五一,懒癌发作,就推迟了 = =.以后还是要按时完成任务.废话不多说,第四章-第六章主要讲了三个内容:键值对.数据读取与保存与Spark的两个共享特性(累加器和广播变量). ...
随机推荐
- 导出Office365中的组及成员
Set-ExecutionPolicy unrestricted $cred = Get-Credential $session = New-PSSession -ConfigurationName ...
- JavaScript 之 ajax
1. AJAX 的概念 AJAX,即 Asynchronous JavaScript and XML(异步的 JavaScript 和 XML) 同步:前面的代码不执行完毕,后面的代码无法执行 异步: ...
- Selenium WebDriver 下 plugin container for firefox has stopped working
用selenium 的webdriver 和 firefox 浏览器做自动化测试,经常会出现 plugin container for firefox has stopped working 如下图所 ...
- sqlserver-查阻塞
模拟阻塞: 打开两个窗口: 窗口一: BEGIN TRANSACTION--开始事务 --等待1分钟 WAITFOR DELAY '00:1'; 窗口二: 查询阻塞:(当前被阻塞的进程id,不 ...
- DFS(DP)---POJ 1014(Dividing)
原题目:http://poj.org/problem?id=1014 题目大意: 有分别价值为1,2,3,4,5,6的6种物品,输入6个数字,表示相应价值的物品的数量,问一下能不能将物品分成两份,是两 ...
- lintcode-384-最长无重复字符的子串
384-最长无重复字符的子串 给定一个字符串,请找出其中无重复字符的最长子字符串. 样例 例如,在"abcabcbb"中,其无重复字符的最长子字符串是"abc" ...
- C#高级编程 (第六版) 学习 第四章:继承
第四章 继承 1,继承的类型 实现继承: 一个类派生于一个基类型,拥有该基类型所有成员字段和函数. 接口继承 一个类型只继承了函数的签名,没有继承任何实现代码. 2,实现继承 class MyDe ...
- shader language学习(1)——shader language简介背景
shader language,称为着色语言,shade在英语是阴影.颜色深浅的意思.shader language基于物体本身属性和光照条件,计算美格橡塑的颜色值. 实际上这种解释具有明显的时代局限 ...
- 【第五周】alpha发布之小组评论
对于昨天的阿尔法发布,有那么几点需要说一下: 1,对这次阿尔法发布的过程,我们组还是基本顺利的,由于之前吃过亏,这次我提前试用了一下投影仪,做了些调试,之后的发布过程起码设备上是正常的. 2,我们的项 ...
- 数组去重复及记录重复个数(以及遍历map的四种方法)
private static void check(String[] array) { // 字符串数组中,含有不重复的字符串有哪些?每一个重复的个数 Map<String,Integer> ...