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;
再次保存成功。