zoukankan      html  css  js  c++  java
  • org.hibernate.TransientObjectException

    使用JPA注解@ManyToMany做一个多对多的用例。

    为了避免在删除主表数据时同时级联删除从表数据,JPA官方文档建议在主表的从表字段使用级联注解:CascadeType.PERSIST,CascadeType.MERGE,进行配置。

    主表代码:

    1   private Set<Hobby> hobby;
    2     
    3    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.EAGER)
    4    @JoinTable(name = "CAT_HOBBY", 
    5        joinColumns = { @JoinColumn(name = "CAT_ID") },
    6        inverseJoinColumns = { @JoinColumn(name = "HOBBY_ID") })
    7    public Set<Hobby> getHobby() {
    8        return hobby;
    9    }

    从表代码:

    1   private Set<Cat> cat;
    2     
    3    @ManyToMany(mappedBy = "hobby",fetch=FetchType.LAZY)
    4    public Set<Cat> getCat() {
    5        return cat;
    6    }
    7    public void setCat(Set<Cat> cat) {
    8        this.cat = cat;
    9    }

    Dao层代码:

     1    public static Object save(Object obj){
     2         Session session = HibernateUtil.getSession();
     3         Transaction tx = null;
     4         try {
     5             tx = session.beginTransaction();
     6             session.save(obj);
     7             tx.commit();
     8         } catch (RuntimeException e) {
     9             if (tx != null) {
    10                 tx.rollback();
    11             }
    12             throw e;
    13         } finally {
    14             session.close();
    15         }
    16         return obj;
    17     }

    main代码:

     1      Cat cat1 = new Cat();
     2         Cat cat2 = new Cat();
     3         cat1.setCat_name("b12_ManyToMany5");
     4         cat2.setCat_name("b12_ManyToMany6");
     5 
     6         Set<Hobby> hobbies = new HashSet<Hobby>();
     7         Hobby hobby1 = new Hobby();
     8         hobby1.setName("球1");
     9         hobbies.add(hobby1);
    10         
    11         Hobby hobby2 = new Hobby();
    12         hobby2.setName("球2");
    13         hobbies.add(hobby2);
    14         
    15         cat1.setHobby(hobbies);
    16         cat2.setHobby(hobbies);
    17         
    18         HibernateUtil.save(cat1);
    19         HibernateUtil.save(cat2);
    20         System.out.println(cat1.getId());
    21         System.out.println(cat2.getId());

    运行main方法,第18行报如下异常,这应该是一个Hibernate实现JPA接口的一个bug。

    org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: b12_ManyToMany_JoinTable.Hobby

    策略一,使用CascadeType.ALL注解,可以保存,但在删除操作时,产生ERROR: ORA-02292: 违反完整约束条件 (WXUATUSER.FK_ODDM1C9RTQFPO2HI2BCR4OUQX) - 已找到子记录。不可取。

    策略二,改用persist方法保存,报异常:detached entity passed to persist。不可取。

    1    tx = session.beginTransaction();
    2    session.persist(obj);
    3    tx.commit();

    策略三,使用Hibernate的注解@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE}),增删改查,达到预期的级联效果,删除主表数据不会级联到从表。可取。

  • 相关阅读:
    (网页)中的简单的遮罩层
    (后端)shiro:Wildcard string cannot be null or empty. Make sure permission strings are properly formatted.
    (网页)jQuery的时间datetime控件在AngularJs中使用实例
    Maven Myeclipse 搭建项目
    MyBatis 环境搭建 (一)
    java 常用方法
    XML 基础
    JS BOM
    js 事件
    js 的使用原则
  • 原文地址:https://www.cnblogs.com/xiluhua/p/4379482.html
Copyright © 2011-2022 走看看