簡體   English   中英

TransientObjectException:對象引用了一個未保存的臨時實例-在執行合並時在刷新之前保存該臨時實例

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM