![](/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.