![](/img/trans.png)
[英]org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing
[英]TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing when I am doing merge
谁能解释我为什么在合并时会出现TransientObjectException。 仅当我在ActivityTestEntity的构造函数中创建RuleTestEntitiy时,问题才重现,如下所示。 如果我进行更新或创建,它不会出现。
提前致谢。
这是一个测试:
@ContextConfiguration(locations = { "classpath:testApplicationContext_db.xml"}) public class TransientObjectExceptionTest extends AbstractTestNGSpringContextTests{ @Autowired SessionFactory sessionFactory; @Test public void testAddTestActivity(){ Session session = sessionFactory.openSession(); Transaction tx1 = session.beginTransaction(); ActivityTestEntity newActivityEntity = new ActivityTestEntity(); session.merge(newActivityEntity); tx1.commit(); session.close(); sessionFactory.close(); }
}
@ContextConfiguration(locations = { "classpath:testApplicationContext_db.xml"}) public class TransientObjectExceptionTest extends AbstractTestNGSpringContextTests{ @Autowired SessionFactory sessionFactory; @Test public void testAddTestActivity(){ Session session = sessionFactory.openSession(); Transaction tx1 = session.beginTransaction(); ActivityTestEntity newActivityEntity = new ActivityTestEntity(); session.merge(newActivityEntity); tx1.commit(); session.close(); sessionFactory.close(); }
}
异常:org.hibernate.TransientObjectException:对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例:com.xxx.RuleTestEntity
@Entity @Table(name = "ACTIVITY_TEST") public class ActivityTestEntity implements Serializable{ private static final long serialVersionUID = 4190826330152288861L; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "ACTIVITY_ID", nullable = false) private long id; @OneToMany(mappedBy = "activity", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true) private Set<RuleTestEntity> rules = new HashSet<>(); public ActivityTestEntity() { RuleTestEntity rule = new RuleTestEntity(); rule.setActivity(this); this.getRules().add(rule); } public long getId() { return id; } public void setId(long id) { this.id = id; } public Set<RuleTestEntity> getRules() { return rules; } public void setRules(Set<RuleTestEntity> rules) { this.rules = rules; }
}
@Entity @Table(name = "ACTIVITY_TEST") public class ActivityTestEntity implements Serializable{ private static final long serialVersionUID = 4190826330152288861L; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "ACTIVITY_ID", nullable = false) private long id; @OneToMany(mappedBy = "activity", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval = true) private Set<RuleTestEntity> rules = new HashSet<>(); public ActivityTestEntity() { RuleTestEntity rule = new RuleTestEntity(); rule.setActivity(this); this.getRules().add(rule); } public long getId() { return id; } public void setId(long id) { this.id = id; } public Set<RuleTestEntity> getRules() { return rules; } public void setRules(Set<RuleTestEntity> rules) { this.rules = rules; }
}
@Entity @Table(name = "RULE_TEST") public class RuleTestEntity implements Serializable { private static final long serialVersionUID = -4208222848601642508L; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "RULE_ID", nullable = false) @XmlElement(name = Identifiable.ID_FIELD_NAME) private long id; @ManyToOne @JoinColumn(name = "ACTIVITY_ID", nullable = true, updatable = false) @XmlTransient private ActivityTestEntity activity; public ActivityTestEntity getActivity() { return activity; } public void setActivity(ActivityTestEntity activity) { this.activity = activity; } public long getId() { return id; } public void setId(long id) { this.id = id; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } RuleTestEntity that = (RuleTestEntity) o; if (id != that.id) { return false; } return activity != null ? activity.equals(that.activity) : that.activity == null; } @Override public int hashCode() { int result = (int) (id ^ (id >>> 32)); result = 31 * result + (activity != null ? activity.hashCode() : 0); return result; }
}
@Entity @Table(name = "RULE_TEST") public class RuleTestEntity implements Serializable { private static final long serialVersionUID = -4208222848601642508L; @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "RULE_ID", nullable = false) @XmlElement(name = Identifiable.ID_FIELD_NAME) private long id; @ManyToOne @JoinColumn(name = "ACTIVITY_ID", nullable = true, updatable = false) @XmlTransient private ActivityTestEntity activity; public ActivityTestEntity getActivity() { return activity; } public void setActivity(ActivityTestEntity activity) { this.activity = activity; } public long getId() { return id; } public void setId(long id) { this.id = id; } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } RuleTestEntity that = (RuleTestEntity) o; if (id != that.id) { return false; } return activity != null ? activity.equals(that.activity) : that.activity == null; } @Override public int hashCode() { int result = (int) (id ^ (id >>> 32)); result = 31 * result + (activity != null ? activity.hashCode() : 0); return result; }
}
当您尝试保存引用未保存实体的实体时,将生成此异常。 您可以先保存引用的实体,然后再保存实体,或者可以在它们之间的关系中添加cascade=CascadeType.All
。
删除构造函数中的代码,然后尝试以下代码:
Session session = sessionFactory.openSession();
Transaction tx1 = session.beginTransaction();
RuleTestEntity rule = new RuleTestEntity();
session.save(rule);
session.refresh(rule);
ActivityTestEntity newActivityEntity = new ActivityTestEntity();
Set<RuleTestEntity> rules = new HashSet<>();
rules.add(rule);
session.merge(newActivityEntity);
tx1.commit();
session.close();
sessionFactory.close();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.