1 我做了一对多和多对一的双向关联关系,在User这一方@ManyToOne已经设置了级联Cascade,这样在测试程序中保存User时,Group也应该自动保存,为什么会抛出以下的异常: (我是按着视频教程里的例子一步一步做的,但视频里却没有异常,是什么原因?)org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.bjsxt.hibernate.model.Group2.如果在测试程序中 HibernateORMappingTest.java:在保存User之前,先把Group也保存了,即加上这一句s.save(g); 就不会出现异常了。可是视频教程里没有这一句,只是设置Cascade级联, 却能通过,这是什么原因呢。User.java:
   @Entity
   @Table(name="t_user")
   public class User {
private int id;
private String name;
private Group group;

@ManyToOne(cascade={CascadeType.ALL} ) //Cascade设置级联
public Group getGroup() {
return group;
}
public void setGroup(Group group) {
this.group = group;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
    }Group.java
   @Entity
   @Table(name ="t_group") 
   public class Group {
private int id;
private String name;
private Set<User> users = new HashSet<User>();
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

@OneToMany(mappedBy="group")
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
   }测试程序 HibernateORMappingTest.java:
  public class HibernateORMappingTest { private static SessionFactory sessionFactory;
@BeforeClass
public static void beforeClass(){
new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
sessionFactory= new AnnotationConfiguration().configure().buildSessionFactory();
}
@AfterClass
public static void afterClass(){
sessionFactory.close();
}
@Test
public void testSaveUser(){
User u = new User();
u.setName("u1");
Group g = new Group();
g.setName("g1");
u.setGroup(g);
Session s= sessionFactory.getCurrentSession();
s.beginTransaction();
//s.save(g); 加上这一句,就不报错了,可是视频教程里没这一句,只是设置了级联Cascade却能通过
s.save(u);
s.getTransaction().commit();
}
        @Test
public void testSchemaExport(){
new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
}
public static void main(String[] args){
beforeClass();
}
}

解决方案 »

  1.   

    User u = new User();
    u.setName("u1");
    Group g = new Group();
    g.setName("g1");
    u.setGroup(g); //主要在这里你设置了级联,但你User依赖的Group都没有先在数据库生成。当然会报错。你可以从数据库角度考虑(hibernate其实也只是映射为数据库操作而已)。你从表里面依赖的主表记录都没有,能将记录保存进去吗?建议你将 show sql 选项打开,你就知道他是怎么工作的。我相信你看SQL还是能看懂的。 视频可能有问题。
      

  2.   

    首先我把OneToMane里的这个级联设置(cascade={CascadeType.ALL} )去掉, 
    再把这一句打开 s.save(g); 
    在保存User这前先保存Group,这样可以成功运行.那么这个级联设不设都没有什么作用了 cascade={CascadeType.ALL
    只要在保存User这前先保存Group就行.   那么这个cascade级联设置不是多余的吗?
      

  3.   

    这么多代码,懒得看了
    解释下这个错误:
     A->B 是many to one, 一般A对B不会有cascade。
    生成并保存A的流程一般如下:
    A a = new A();
    ...
    a.setB(b)//注意,如果次数的b不是从数据库中加载的,或者说b只是个游离态
    就会出现上面的问题。
      

  4.   

    @OneToMany(fetch=FetchType.EAGER,targetEntity = Email.class, cascade = {
    CascadeType.PERSIST, CascadeType.REMOVE, CascadeType.MERGE,
    CascadeType.REFRESH })
    训序不要搞反了就好了
      

  5.   

    原因是複製的之前那一個項目裡是使用xml文件配置的映射,而在此項目裡用Annotation修改cascade,而沒有在cfg.xml中把相應的映射配置為<mapping class="...">。