简体   繁体   English

org.hibernate.TransientObjectException:object引用未保存的瞬态实例 - 在刷新之前保存瞬态实例

[英]org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing

In my project I have User , Role , UserRole and BloodGroup entities. 在我的项目中,我有UserRoleUserRoleBloodGroup实体。 Firstly I take List<BloodGroup> from DB and set to User . 首先,我从DB中获取List<BloodGroup>并设置为User Then I give User and Role entites to UserRole . 然后我将UserRole entites给UserRole After that I insert User to DB, then I try to insert UserRole , but I get an error. 之后我将User插入DB,然后我尝试插入UserRole ,但是我收到一个错误。 When I look to DB, the ID of BloodGroup isn't inserted in User table. 当我查看DB时, BloodGroup的ID未插入User表中。

If I choose the first BloodGroup in the list, I get an error. 如果我选择列表中的第一个BloodGroup ,我会收到错误。 Other options is normal. 其他选择是正常的。

I look at the internet, I found cascade = CascadeType.ALL , but this add same data to BloodGroup , which means I have more Arh+ BloodGroup . 我看看互联网,我发现cascade = CascadeType.ALL ,但这会向BloodGroup添加相同的数据,这意味着我有更多的Arh + BloodGroup

The entities: 实体:

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

}

Controller: 控制器:

user.setBloodgroup(bloodGroupImpl.getBloodGroupById(bGroup));
user.setUserid(userImpl.insertUserProfile(user));
userRoleImpl.insertUserRole(user,role);

DAO: 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);
}

Log: 日志:

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)

your issue will be resolved by properly defining cascading depedencies or by saving the referenced entities before saving the entity that references. 您的问题将通过正确定义级联依赖关系或通过在保存引用的实体之前保存引用的实体来解决。 Defining cascading is really tricky to get right because of all the subtle variations in how they are used. 定义级联是非常棘手的,因为它们的使用方式存在细微变化。

Here is how you can define cascades: 以下是如何定义级联:

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

}

In this scenario, every time you save, update, delete, etc Userrole, the assocaited Role and User will also be saved, updated... 在这种情况下,每次保存,更新,删除等Userrole时,关联的角色和用户也将被保存,更新......

Again, if your use case demands that you do not modify User or Role when updating Userrole, then simply save User or Role before modifying Userrole 同样,如果您的用例要求您在更新Userrole时不修改用户或角色,那么只需在修改Userrole之前保存用户或角色

Additionally, bidirectional relationships have a one-way ownership. 此外,双向关系具有单向所有权。 In this case, User owns Bloodgroup. 在这种情况下,用户拥有Bloodgroup。 Therefore, cascades will only proceed from User -> Bloodgroup. 因此,级联只会从用户 - >血型进行。 Again, you need to save User into the database (attach it or make it non-transient) in order to associate it with Bloodgroup. 同样,您需要将用户保存到数据库中(将其附加或使其成为非瞬态),以便将其与Bloodgroup相关联。

I had a similar problem and although I made sure that referenced entities were saved first it keeps failing with the same exception. 我有一个类似的问题,虽然我确保首先保存引用的实体,但它仍然失败,但同样的异常。 After hours of investigation it turns out that the problem was because the "version" column of the referenced entity was NULL. 经过数小时的调查后发现问题是因为被引用实体的“版本”列是NULL。 In my particular setup i was inserting it first in an HSQLDB(that was a unit test) a row like that: 在我的特定设置中,我首先将它插入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);

The problem of the above is the version column used by hibernate was set to null, so even if the object was correctly saved, Hibernate considered it as unsaved. 上面的问题是hibernate使用的版本列被设置为null,所以即使对象被正确保存,Hibernate也认为它是未保存的。 When making sure the version had a NON-NULL(1 in this case) value the exception disappeared and everything worked fine. 当确保版本具有NON-NULL(在这种情况下为1)值时,异常消失并且一切正常。

I am putting it here in case someone else had the same problem, since this took me a long time to figure this out and the solution is completely different than the above. 我把它放在这里以防其他人有同样的问题,因为这花了我很长时间才弄明白,解决方案与上述完全不同。

I Solved this problem adding @Cascade to the @ManyToOne attribute. 我解决了将@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;

Instead of passing reference object passed the saved object, below is explanation which solve my issue: 而不是传递参考对象传递保存的对象,下面是解释我的问题的解释:

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

//right
Role savedEntity= entityManager.persist(role);
user.setRole(savedEntity);
entityManager.persist(user)

In my case setting the referenced object to NULL in my object before the merge o save method solve the problem, in my case the referenced object was catalog, that doesn't need to be saved, because in some cases I don't have it even. 在我的情况下,在merge o save方法解决问题之前在我的对象中将引用的对象设置为NULL,在我的情况下,引用的对象是目录,不需要保存,因为在某些情况下我没有它甚至。

    fisEntryEB.setCatStatesEB(null);

    (fisEntryEB) getSession().merge(fisEntryEB);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 org.hibernate.TransientObjectException: 对象引用了一个未保存的瞬态实例 - org.hibernate.TransientObjectException: object references an unsaved transient instance org.hibernate.TransientObjectException:对象是未保存的瞬态实例-在合并之前保存瞬态实例 - org.hibernate.TransientObjectException: object is an unsaved transient instance - save the transient instance before merging 休眠条件-org.hibernate.TransientObjectException:对象引用了未保存的临时实例 - Hibernate criteria - org.hibernate.TransientObjectException: object references an unsaved transient instance TransientObjectException:对象引用了一个未保存的临时实例-在执行合并时在刷新之前保存该临时实例 - TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing when I am doing merge 春季-休眠-org.hibernate.TransientObjectException:对象引用了一个未保存的临时实例 - spring - hibernate - org.hibernate.TransientObjectException: object references an unsaved transient instance 使用 Hibernate 保存 object object 引用未保存的瞬态实例 在刷新之前保存瞬态实例 - save the object using Hibernate object references an unsaved transient instance save the transient instance before flushing 对象引用了一个未保存的临时实例-使用休眠空间在刷新之前保存该临时实例 - object references an unsaved transient instance - save the transient instance before flushing using hibernate spatial 休眠:对象引用了一个未保存的瞬态实例-在刷新之前保存该瞬态实例 - Hibernate : object references an unsaved transient instance - save the transient instance before flushing HIbernate - 对象引用一个未保存的瞬态实例 - 在刷新之前保存瞬态实例 - HIbernate - object references an unsaved transient instance - save the transient instance before flushing 如何修复 Hibernate“对象引用未保存的瞬态实例 - 在刷新前保存瞬态实例”错误 - How to fix the Hibernate "object references an unsaved transient instance - save the transient instance before flushing" error
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM