![](/img/trans.png)
[英]org.hibernate.TransientObjectException: object references an unsaved transient instance
[英]org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing
在我的項目中,我有User
, Role
, UserRole
和BloodGroup
實體。 首先,我從DB中獲取List<BloodGroup>
並設置為User
。 然后我將User
和Role
entites給UserRole
。 之后我將User
插入DB,然后我嘗試插入UserRole
,但是我收到一個錯誤。 當我查看DB時, BloodGroup
的ID未插入User
表中。
如果我選擇列表中的第一個BloodGroup
,我會收到錯誤。 其他選擇是正常的。
我看看互聯網,我發現cascade = CascadeType.ALL
,但這會向BloodGroup
添加相同的數據,這意味着我有更多的Arh + BloodGroup
。
實體:
@Entity
@Table(name="USERS")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long userid;
@OneToMany(mappedBy="user")
private List<Userrole> userroles;
//bi-directional many-to-one association to Bloodgroup
@ManyToOne
@JoinColumn(name="BLOODGRUPID")
private Bloodgroup bloodgroup;
}
@Entity
public class Bloodgroup implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private int bloodgroupid;
private String bloodgroupname;
@OneToMany(mappedBy="bloodgroup")
private List<User> users;
}
@Entity
public class Userrole implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long userroleid;
private Timestamp createddate;
private Timestamp deleteddate;
private String isactive;
//bi-directional many-to-one association to Role
@ManyToOne
@JoinColumn(name="ROLEID")
private Role role;
//bi-directional many-to-one association to User
@ManyToOne
@JoinColumn(name="USERID")
private User user;
}
控制器:
user.setBloodgroup(bloodGroupImpl.getBloodGroupById(bGroup));
user.setUserid(userImpl.insertUserProfile(user));
userRoleImpl.insertUserRole(user,role);
DAO:
public void insertUserRole(User user, Role role) {
Session session =getHibernateTemplate().getSessionFactory().getCurrentSession();
Userrole uRole = new Userrole();
uRole.setIsactive("1");
uRole.setRole(role);
uRole.setUser(user);
session.save(uRole);
session.flush();
}
public void insertUserProfile(User user) {
Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
session.save(user);
}
日志:
Hibernate:
insert
into
IU.Userrole
(userroleid, createddate, deleteddate, isactive, ROLEID, USERID)
values
(default, ?, ?, ?, ?, ?)
05.Şub.2012 19:23:29 com.sun.faces.application.ActionListenerImpl processAction
SEVERE: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.iu.eblood.model.Bloodgroup
javax.faces.el.EvaluationException: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.iu.eblood.model.Bloodgroup
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:775)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1267)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:103)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:310)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
您的問題將通過正確定義級聯依賴關系或通過在保存引用的實體之前保存引用的實體來解決。 定義級聯是非常棘手的,因為它們的使用方式存在細微變化。
以下是如何定義級聯:
@Entity
public class Userrole implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private long userroleid;
private Timestamp createddate;
private Timestamp deleteddate;
private String isactive;
//bi-directional many-to-one association to Role
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="ROLEID")
private Role role;
//bi-directional many-to-one association to User
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="USERID")
private User user;
}
在這種情況下,每次保存,更新,刪除等Userrole時,關聯的角色和用戶也將被保存,更新......
同樣,如果您的用例要求您在更新Userrole時不修改用戶或角色,那么只需在修改Userrole之前保存用戶或角色
此外,雙向關系具有單向所有權。 在這種情況下,用戶擁有Bloodgroup。 因此,級聯只會從用戶 - >血型進行。 同樣,您需要將用戶保存到數據庫中(將其附加或使其成為非瞬態),以便將其與Bloodgroup相關聯。
我有一個類似的問題,雖然我確保首先保存引用的實體,但它仍然失敗,但同樣的異常。 經過數小時的調查后發現問題是因為被引用實體的“版本”列是NULL。 在我的特定設置中,我首先將它插入HSQLDB(這是一個單元測試),就像這樣:
INSERT INTO project VALUES (1,1,'2013-08-28 13:05:38','2013-08-28 13:05:38','aProject','aa',NULL,'bb','dd','ee','ff','gg','ii',NULL,'LEGACY','0','CREATED',NULL,NULL,1,'0',NULL,NULL,NULL,NULL,'0','0', NULL);
上面的問題是hibernate使用的版本列被設置為null,所以即使對象被正確保存,Hibernate也認為它是未保存的。 當確保版本具有NON-NULL(在這種情況下為1)值時,異常消失並且一切正常。
我把它放在這里以防其他人有同樣的問題,因為這花了我很長時間才弄明白,解決方案與上述完全不同。
我解決了將@Cascade添加到@ManyToOne屬性的問題。
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
@ManyToOne
@JoinColumn(name="BLOODGRUPID")
@Cascade({CascadeType.MERGE, CascadeType.SAVE_UPDATE})
private Bloodgroup bloodgroup;
而不是傳遞參考對象傳遞保存的對象,下面是解釋我的問題的解釋:
//wrong
entityManager.persist(role);
user.setRole(role);
entityManager.persist(user)
//right
Role savedEntity= entityManager.persist(role);
user.setRole(savedEntity);
entityManager.persist(user)
在我的情況下,在merge o save方法解決問題之前在我的對象中將引用的對象設置為NULL,在我的情況下,引用的對象是目錄,不需要保存,因為在某些情況下我沒有它甚至。
fisEntryEB.setCatStatesEB(null);
(fisEntryEB) getSession().merge(fisEntryEB);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.