it-swarm.com.ru

org.hibernate.TransientObjectException: объект ссылается на несохраненный временный экземпляр - сохраните временный экземпляр перед сбросом

В моем проекте у меня есть сущности User, Role, UserRole и BloodGroup. Сначала я беру List<BloodGroup> из БД и устанавливаю User. Затем я даю User и Role права на UserRole. После этого я вставляю User в БД, затем пытаюсь вставить UserRole, но получаю ошибку. Когда я смотрю на БД, идентификатор BloodGroup не вставляется в таблицу 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)
20
eaktas

ваша проблема будет решена путем правильного определения каскадных зависимостей или путем сохранения ссылочных объектов перед сохранением сущности, на которую ссылаются. Определить каскадирование действительно сложно из-за всех тонких различий в том, как они используются.

Вот как вы можете определить каскады:

@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, связанные роль и пользователь также сохраняются, обновляются ...

Опять же, если ваш вариант использования требует, чтобы вы не изменяли User или Role при обновлении Userrole, то просто сохраните User или Role перед изменением Userrole

Кроме того, двунаправленные отношения имеют одностороннюю собственность. В этом случае Пользователь владеет Bloodgroup. Поэтому каскады будут исходить только из User -> Bloodgroup. Опять же, вам нужно сохранить пользователя в базу данных (присоединить его или сделать его непереходным), чтобы связать его с группой крови.

41
John Ericksen

У меня была похожая проблема, и хотя я позаботился о том, чтобы ссылочные объекты были сохранены первыми, он продолжает давать сбой за тем же исключением. После нескольких часов исследования выясняется, что проблема была в том, что столбец «версия» ссылочной сущности был 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), исключение исчезло, и все работало нормально.

Я помещу это здесь в случае, если у кого-то еще была та же самая проблема, так как мне потребовалось много времени, чтобы понять это, и решение полностью отличается от вышеупомянутого.

11
isaac.hazan

Я решил эту проблему, добавив @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;
1
Federico Traiman

В моем случае установка ссылочного объекта на NULL в моем объекте до того, как метод слияния или сохранения решит проблему, в моем случае ссылочным объектом был каталог, который не нужно сохранять, потому что в некоторых случаях у меня его нет четное.

    fisEntryEB.setCatStatesEB(null);

    (fisEntryEB) getSession().merge(fisEntryEB);
0
Axel Osorio

Вместо передачи ссылочного объекта переданного сохраненного объекта, ниже приведено объяснение, которое решает мою проблему:

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

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