• 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}),增删改查,达到预期的级联效果,删除主表数据不会级联到从表。可取。

  • 相关阅读:
    Git与GitHub的基本使用
    HTML&CSS基础-外边框
    HTML&CSS基础-内边框
    SHELL脚本编程变量输入
    GoLang基础数据类型-切片(slice)详解
    GoLang基础数据类型--->数组(array)详解
    SHELL脚本编程的运算符
    SHELL脚本编程变量详解
    HTML&CSS基础-边框简写属性
    GoLang基础数据类型--->字符串处理大全
  • 原文地址:https://www.cnblogs.com/xiluhua/p/4379482.html
Copyright © 2020-2023  润新知