• 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一个对象一样,但是简单了很多,代码如下:

    1. public class CopyHandle extends LoggerBase {
    2. private static CopyHandle instance = null;
    3.  
    4. private CopyHandle(){}
    5. public static CopyHandle getInstance(){
    6. if(null == instance){
    7. instance = new CopyHandle();
    8. }
    9. return instance;
    10. }
    11.  
    12. public Object copy(Object object) {
    13. Object objectCopy = null;
    14. try {
    15. if(null == object) return null;
    16.  
    17. Class<?> classType = object.getClass();
    18. Field fields[] = classType.getDeclaredFields();
    19.  
    20. objectCopy = classType.getConstructor(new Class[] {}).newInstance(new Object[] {});
    21.  
    22. Field field = null;
    23. String suffixMethodName;
    24. Method getMethod, setMethod;
    25. Object value = null;
    26. for (int i = 0; i < fields.length; i++) {
    27. field = fields[i];
    28. suffixMethodName = field.getName().substring(0, 1).toUpperCase() + (field.getName().length()>1?field.getName().substring(1):"");
    29.  
    30. getMethod = classType.getMethod("get" + suffixMethodName, new Class[] {});
    31. setMethod = classType.getMethod("set" + suffixMethodName, new Class[] { field.getType() });
    32.  
    33. value = getMethod.invoke(object, new Object[] {});
    34. if(null == value){
    35. if(field.getType().getName().equalsIgnoreCase("java.lang.String")){
    36. setMethod.invoke(objectCopy, new Object[] { "" });
    37. }
    38. } else {
    39. setMethod.invoke(objectCopy, new Object[] { value });
    40. }
    41. }
    42. } catch (NoSuchMethodException e) {
    43. // TODO: handle exception
    44. this.logger.error("CopyHandle.copy(): NoSuchMethodException: "+ e);
    45. } catch (Exception e) {
    46. // TODO: handle exception
    47. this.logger.error("CopyHandle.copy(): Exception: "+ e);
    48. }finally{
    49. return objectCopy;
    50. }
    51. }
    52.  
  • 相关阅读:
    react 之 ref
    再看redux
    localtunnel内网服务器暴露至公网
    Relay GraphQL理解
    微信小程序
    React Router
    webpack
    Redux
    bootstrap
    jQuery中.bind() .live() .delegate() .on()区别
  • 原文地址:https://www.cnblogs.com/libin6505/p/10224582.html
Copyright © 2020-2023  润新知