2012-02-05 51 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) 
相关问题