2012-02-05 67 views
19

在我的項目中,我有User,,UserRoleBloodGroup實體。首先我從DB獲取List<BloodGroup>並設置爲User。然後,我將UserRole轉交給UserRole。之後,我將User插入數據庫,然後嘗試插入UserRole,但出現錯誤。當我查看DB時,BloodGroup的ID未插入User表中。org.hibernate.TransientObjectException:對象引用未保存的瞬態實例 - 保存沖洗前的瞬態實例

如果我在列表中選擇第一個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) 
+0

你能提供引發錯誤的代碼?只是爲了看看你如何保存實例。 – ivowiblo 2012-02-05 15:45:28

+2

而不是嘗試在互聯網上發現的隨機事件,你應該嘗試瞭解錯誤的含義,檢測拋出異常的位置並修復錯誤。向我們展示完整的堆棧跟蹤和引發此異常的代碼。 – 2012-02-05 16:16:43

回答

39

您的問題將通過適當定義級聯depedencies或保存實體引用之前保存引用的實體來解決。由於使用方式的細微差異,定義級聯確實非常棘手。

這裏是你如何定義級聯:

@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的assocaited角色和用戶也將被保存,更新...

再次,如果你的使用情況要求,更新的UserRole當你沒有修改用戶或角色,然後只需保存用戶或角色修改的UserRole

之前此外,雙向的關係有一個單向的所有權。在這種情況下,用戶擁有Bloodgroup。因此,級聯只能從User-> Bloodgroup進行。同樣,您需要將用戶保存到數據庫(附加或使其成爲非瞬態),以便將其與Bloodgroup關聯。

10

我有一個類似的問題,雖然我確保引用的實體先保存,但它保持與相同的異常失敗。 經過數小時的調查後發現問題是因爲被引用實體的「版本」列爲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也認爲它是未保存的。確保版本具有NON-NULL(本例中爲1)值時,異常消失,一切正常。

我把它放在這裏以防別人遇到同樣的問題,因爲這花了我很長時間才弄清楚,解決方案與上述完全不同。

+2

休眠總是給出最糟糕的錯誤信息......我工作生活的禍根...... – Serge 2015-09-17 18:44:11

+1

謝謝你的回答....同樣的問題剛剛讓我把我的頭髮撕了出來......我試着各種各樣的事務並級聯選項只是發現問題是一個NULL版本字段...找不到其他地方的文件這個問題。 – 2015-11-30 03:12:45

+1

謝謝你的回答 - 在我使用CommandLineRunner在spring中創建用戶時也是如此(在NULL的情況下也有一些值,從來不會猜到對象被認爲是未保存的) – lenach87 2016-05-16 15:02:07

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; 
0

而不是通過引用對象傳遞的保存對象,下面是解決我的問題的解釋:

//wrong 
entityManager.persist(role); 
user.setRole(role); 
entityManager.persist(user) 

//right 
Role savedEntity= entityManager.persist(role); 
user.setRole(savedEntity); 
entityManager.persist(user) 
相關問題