zoukankan      html  css  js  c++  java
  • hibernate-annotation CascadeType.PERSIST不起作用的解决方法

    有如下两个实体类 , Student和Grade 为多对一关系。

    Student.java

     1 @Entity
     2 public class Student {
     3     private Integer id;
     4     private String name;
     5     private Grade grade;
     6     @Id
     7     @GeneratedValue(strategy=GenerationType.AUTO)
     8     public Integer getId() {
     9         return id;
    10     }
    11     public void setId(Integer id) {
    12         this.id = id;
    13     }
    14     public String getName() {
    15         return name;
    16     }
    17     public void setName(String name) {
    18         this.name = name;
    19     }
    20     @ManyToOne(cascade={CascadeType.PERSIST})
    21     @JoinColumn(name="gradeid")
    22     public Grade getGrade() {
    23         return grade;
    24     }
    25     public void setGrade(Grade grade) {
    26         this.grade = grade;
    27     }
    28     
    29 }

    Grade.java

     1 @Entity
     2 public class Grade {
     3 
     4     private Integer id;
     5     private String name;
     6     
     7     @Id
     8     @GeneratedValue(strategy=GenerationType.AUTO)
     9     public Integer getId() {
    10         return id;
    11     }
    12     public void setId(Integer id) {
    13         this.id = id;
    14     }
    15     public String getName() {
    16         return name;
    17     }
    18     public void setName(String name) {
    19         this.name = name;
    20     }
    21 
    22 }

    可以看到Student类的grade属性已经设置了   @ManyToOne(cascade={CascadeType.PERSIST})

    但只save Student对象时依然会报 org.hibernate.TransientObjectException 异常,如下:

    public class Init {
        public static void main(String[] args) {
            Session session = HibernateUtil.getSessionFactory().getCurrentSession();
            session.beginTransaction();
            
            Grade g = new Grade();
            g.setName("一班");
            
            Student s = new Student();
            s.setName("张三");
            s.setGrade(g);
            
            session.save(s);
            
            session.getTransaction().commit();
        
        }
    }

    运行结果:

    Exception in thread "main" org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: accp.hib.Grade

    解决办法如下:

    方法一:改用persist方法来保存

    把session.save(s); 更改为 session.persist(s);

    再次保存成功。

    Hibernate: select hibernate_sequence.nextval from dual
    Hibernate: select hibernate_sequence.nextval from dual
    Hibernate: insert into Grade (name, id) values (?, ?)
    Hibernate: insert into Student (gradeid, name, id) values (?, ?, ?)

    方法二:使用hibernate的自定义的级联,不要使用jpa的

    把Student类grade的注解改为hibernate的注解

    @ManyToOne(cascade={CascadeType.PERSIST})
    @JoinColumn(name="gradeid")

    改为:

    @ManyToOne
    @JoinColumn(name="gradeid")
    @Cascade(value={CascadeType.SAVE_UPDATE})

    注意,这里的CascadeType和@Cascade都是org.hibernate.annotations包下的,所以把

    import javax.persistence.CascadeType;

    改为:import org.hibernate.annotations.CascadeType;

    并加上:import org.hibernate.annotations.Cascade;

    再次保存成功。

  • 相关阅读:
    C++实现网络寻路
    java实现生日相同概率
    java实现生日相同概率
    Mysql 锁表 for update (引擎/事务)
    mysql(for update)悲观锁总结与实践
    Select For update语句浅析
    Mysql查询语句使用select.. for update导致的数据库死锁分析
    数据库中Select For update语句的解析
    【转载】支付宝运营架构中柔性事务指的是什么?
    互联网支付系统整体架构详解
  • 原文地址:https://www.cnblogs.com/likailan/p/3413469.html
Copyright © 2011-2022 走看看