問題:object references an unsaved transient instance - save the transient instance before flushing_hibernate

來源:互聯網
上載者:User

1、報錯日誌:
在儲存xx資訊時,如果選了裝置資訊,後台不會報錯,如果沒選裝置,就會報錯,報錯資訊如下:

[2017-08-10 08:41:02] org.springframework.web.servlet.HandlerExecutionChain.triggerAfterCompletion(HandlerExecutionChain.java:173) <ERROR> HandlerInterceptor.afterCompletion threw exceptionorg.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.hcepms.model.device.Device    org.hibernate.engine.internal.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:279)    at org.hibernate.type.EntityType.getIdentifier(EntityType.java:462)    at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:281)    at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:291)    at org.hibernate.type.TypeHelper.findDirty(TypeHelper.java:296)    at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:4144)    at org.hibernate.event.internal.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:532)    at org.hibernate.event.internal.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:215)    at org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:142)    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:216)    at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:85)    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:38)    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282)    at com.hcepms.base.dao.BaseDaoImpl.save(BaseDaoImpl.java:38)    at com.hcepms.base.service.BaseServiceImpl.save(BaseServiceImpl.java:38)    at com.hcepms.base.interceptor.SecurityAndLogInterceptor.afterCompletion(SecurityAndLogInterceptor.java:150)    at org.springframework.web.servlet.HandlerExecutionChain.triggerAfterCompletion(HandlerExecutionChain.java:170)    at org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletion(DispatcherServlet.java:1297)    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:976)    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:895)    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967)    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:869)    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843)    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)    at org.springframework.orm.hibernate5.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:151)    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)    at java.lang.Thread.run(Thread.java:745)log4j:ERROR Failed to write [[2017-08-10 08:41:02] <http-nio-8080-exec-5> org.springframework.web.servlet.HandlerExecutionChain.triggerAfterCompletion(HandlerExecutionChain.java:173) <ERROR> HandlerInterceptor.afterCompletion threw exception

2、hibernate.hbm.xml

<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.hcepms.model.device.enter" default-access="field"><class name="DeviceEnterDetail" table="T_DEVICE_ENTER_DETAIL">  <many-to-one     name="device"     class="com.hcepms.model.device.base.Device"     fetch="select"     lazy="false"//不消極式載入     not-found="ignore">//指定引用的外鍵不存在時"忽略"    <column name="DEVICE_"/>  </many-to-one></class></hibernate-mapping>

3、controller中儲存方法的代碼:

/**  *   * 儲存XX資訊  * @author zhangsan   * @date 2016年8月2日  * @param deviceEnterDetail XX資訊  * @param session  * @return  * @throws Exception  */@ResponseBody@RequestMapping("/saveOrUpdateDetail")public Json saveOrUpdateDetail(DeviceEnterDetail deviceEnterDetail,HttpSession session)throws Exception{    Json json = new Json();    String operat = (deviceEnterDetail.getId() == null ? "新增" : "編輯");    try {        SessionInfo sessionInfo = (SessionInfo)session.getAttribute("sessionInfo");        UserDetail user = new UserDetail();        user.setId(sessionInfo.getUserId());        if(deviceEnterDetail.getId() == null){            deviceEnterDetail.setCreateDate(new Date());            deviceEnterDetail.setCreateUser(user);            deviceEnterDetail.setStatus(1);        }else{            deviceEnterDetail.setUpdateDate(new Date());            deviceEnterDetail.setUpdateUser(user);        }        dEDetailService.saveOrUpdate(deviceEnterDetail);        json.setSuccess(true);        json.setMsg(operat + "XX資訊成功");    } catch (Exception e) {        log.error(operat + "XX信資訊異常",e);        json.setSuccess(true);        json.setMsg(operat + "XX信細資訊失敗");    }    return json;}

4、頁面如下圖
裝置可選,可不選

<label for="useDev" class="col-xs-1 control-label" style="white-space: nowrap;"><a class="require"><i class="icon-Asterisk"></i></a>裝置名稱</label><div class="col-xs-3">     <div class="threepoint icon-DownMenu3" onclick="selectDevice()">     </div>     <input type="text" class="form-control sel" id="useDev"             placeholder="請選擇裝置" readonly>     <input type="hidden" id="deviceId" name="device.id" />     </div> 

5、解決方案
在controller中saveOrUpdateDetail方法中,在dEDetailService.saveOrUpdate(deviceEnterDetail);之前添加

if(deviceEnterDetail.getDevice() == null || deviceEnterDetail.getDevice().getId() == null){      deviceEnterDetail.setDevice(null);}

6、小結:
本人並沒有使用級聯。是儲存單個對象,而這個有關聯的對象,你的頁面可以對這個關聯對象不選值,就是給關聯對象不選id值,這樣的話?springmvc會把你的關聯對象重新new一個Null 物件賦給此對象,而這個Null 物件在資料庫肯定是沒有的,所以在儲存該對象的時候就會報關聯的沒選值的對象為瞬時態的錯誤。解除決辦法就是在hibernate儲存單個對象之前,做一下判斷關聯的對象是否為空白(注意關聯的對象實體配置必須配製關聯對象可為null),如果為空白,則將關聯對象set為null。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.