• 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;

    再次保存成功。

  • 相关阅读:
    AODV点点滴滴
    让控件的DropdownMenu或者PopupMenu弹出来
    如何让CoolBar控件的Bands在同一行上
    怎样在InstallShield的Basic MSI Project中用InstallScript添加路径
    VC调用Delphi制作的动态链接库如何互相传递字符串
    Delphi 中用 GetEnvironmentVariable 获取常用系统变量
    如何在工具栏或者其他的控件上显示其他控件的Hint
    企业信息开发平台(1)序
    对.Net 垃圾回收的C#编程相关方面(Finalize 和Dispose(bool disposing)和 Dispose())的一些理解体会(转)
    android上怎样让一个Service开机自动启动
  • 原文地址:https://www.cnblogs.com/likailan/p/3413469.html
Copyright © 2020-2023  润新知