Hibernate 删除记录惨遭失败
Posted
技术标签:
【中文标题】Hibernate 删除记录惨遭失败【英文标题】:Hibernate delete record miserably fails 【发布时间】:2013-11-27 06:43:05 【问题描述】:我一直在用头撞墙。 session.delete(object) 可悲地无法向我显示这些消息。
当我复制并粘贴休眠生成的删除sql,并在SQLDeveloper中运行该sql时,它运行得很好并删除了记录,但它在休眠中不起作用。 奇怪... 我猜可能是因为“select - before - update”,所以我将 select-before-update="false" 放在我的 hbm 文件中,但我看到它仍然在删除之前发出了 select 语句。 我做错了什么?
SimpleSystemLogFilter :)
log # 0 at Wed Nov 27 15:37:29 KST 2013 := http://172.16.0.27:9090/sideEffect/properties.do?action=deleteItem&mea_class_no=ggg&grade=1 by test(user# 26)
null
Trying to get method name with param name : action
trying to return method name of : deleteItem
Trying to get method name with param name : action
trying to return method name of : deleteItem
Hibernate:
select
mea_class__.mea_class_no,
mea_class__.grade,
mea_class__.HIGHER_CLASS_NO as HIGHER_C3_31_,
mea_class__.HIGHER_CLASS_GRADE as HIGHER_C4_31_,
mea_class__.CLASS_LEVEL as CLASS_LE5_31_,
mea_class__.CLASS_KOR_NAME as CLASS_KO6_31_,
mea_class__.CLASS_ENG_NAME as CLASS_EN7_31_,
mea_class__.CLASS_CONT as CLASS_CO8_31_,
mea_class__.ITEM_GRP_CODE as ITEM_GRP9_31_,
mea_class__.REGIST_ID as REGIST_10_31_,
mea_class__.UPDATE_ID as UPDATE_11_31_,
mea_class__.TRACE_MANAGE_TARGET_YN as TRACE_M12_31_,
mea_class__.USE_YN as USE_YN13_31_,
mea_class__.code_age as code_ag14_31_,
mea_class__.TRACEABILITY as TRACEAB15_31_,
mea_class__.IS_IN_USE as IS_IN_U16_31_
from
MEA_CLASS_NO mea_class__
where
mea_class__.mea_class_no=?
and mea_class__.grade=?
15:37:29,946 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - ggg
15:37:29,947 TRACE BasicBinder:84 - binding parameter [2] as [INTEGER] - 1
15:37:29,950 TRACE BasicExtractor:68 - Found [null] as column [HIGHER_C3_31_]
15:37:29,950 TRACE BasicExtractor:74 - Found [0] as column [HIGHER_C4_31_]
15:37:29,950 TRACE BasicExtractor:74 - Found [1] as column [CLASS_LE5_31_]
15:37:29,950 TRACE BasicExtractor:74 - Found [ggg] as column [CLASS_KO6_31_]
15:37:29,951 TRACE BasicExtractor:74 - Found [ggg] as column [CLASS_EN7_31_]
15:37:29,951 TRACE BasicExtractor:68 - Found [null] as column [CLASS_CO8_31_]
15:37:29,951 TRACE BasicExtractor:68 - Found [null] as column [ITEM_GRP9_31_]
15:37:29,952 TRACE BasicExtractor:68 - Found [null] as column [REGIST_10_31_]
15:37:29,952 TRACE BasicExtractor:68 - Found [null] as column [UPDATE_11_31_]
15:37:29,952 TRACE BasicExtractor:74 - Found [Y] as column [TRACE_M12_31_]
15:37:29,952 TRACE BasicExtractor:74 - Found [Y] as column [USE_YN13_31_]
15:37:29,953 TRACE BasicExtractor:74 - Found [0] as column [code_ag14_31_]
15:37:29,953 TRACE BasicExtractor:74 - Found [1] as column [TRACEAB15_31_]
15:37:29,953 TRACE BasicExtractor:74 - Found [1] as column [IS_IN_U16_31_]
deleteMeaClassNo().jobStat := false
Hibernate:
delete
from
JUNC_ITEM_HISTORY
where
mea_class_no=?
and grade=?
15:37:29,974 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - ggg
15:37:29,975 TRACE BasicBinder:84 - binding parameter [2] as [INTEGER] - 1
Hibernate:
delete
from
MEA_CLASS_NO
where
mea_class_no=?
and grade=?
15:37:29,977 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - ggg
15:37:29,977 TRACE BasicBinder:84 - binding parameter [2] as [INTEGER] - 1
15:37:29,980 INFO AbstractBatchImpl:195 - HHH000010: On release of batch it still contained JDBC statements
11월 27, 2013 3:37:29 오후 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet springDispatcherServlet threw exception
org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0]; actual row count: 0; expected: 1
at org.hibernate.jdbc.Expectations$BasicExpectation.checkBatched(Expectations.java:81)
at org.hibernate.jdbc.Expectations$BasicExpectation.verifyOutcome(Expectations.java:73)
at org.hibernate.engine.jdbc.batch.internal.NonBatchingBatch.addToBatch(NonBatchingBatch.java:59)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3357)
at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:3560)
at org.hibernate.action.internal.EntityDeleteAction.execute(EntityDeleteAction.java:102)
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:393)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:385)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:308)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:339)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1240)
at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:404)
at org.hibernate.engine.transaction.internal.jdbc.JdbcTransaction.beforeTransactionCommit(JdbcTransaction.java:101)
at org.hibernate.engine.transaction.spi.AbstractTransactionImpl.commit(AbstractTransactionImpl.java:175)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:480)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:392)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
at properties.SimplePropertiesDAO$$EnhancerByCGLIB$$707c88a9.deleteMeaClassNo(<generated>)
at properties.SimplePropertiesDelegate.deleteItem(SimplePropertiesDelegate.java:602)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.web.servlet.mvc.multiaction.MultiActionController.invokeNamedMethod(MultiActionController.java:471)
at org.springframework.web.servlet.mvc.multiaction.MultiActionController.handleRequestInternal(MultiActionController.java:408)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:917)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:813)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:798)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at system.log.SimpleSystemLogFilter.doFilter(SimpleSystemLogFilter.java:65)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at system.security.SecurityFilter.doFilter(SecurityFilter.java:92)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:259)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Unknown Source)
这是我的 hbm 文件
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="MEA_CLASS_NO" name="foreign.Mea_class_no"
>
<composite-id name="compositeKey"
class="foreign.MeaClassNoCompositeKey"
>
<key-property name="mea_class_no" />
<key-property name="grade"/>
</composite-id>
<property name="mea_class_no" insert="false" update="false">
<column name="mea_class_no" />
</property>
<many-to-one name="gradeObj" lazy="false" not-found="ignore"
class="foreign.SimpleForeignGrade" insert="false" update="false">
<column name="grade"></column>
</many-to-one>
<property name="grade" insert="false" update="false">
<column name="grade"/>
</property>
<property name="higher_class_no" >
<column name="HIGHER_CLASS_NO"/>
</property>
<property name="higher_class_grade" >
<column name="HIGHER_CLASS_GRADE"/>
</property>
<property name="class_level">
<column name="CLASS_LEVEL"/>
</property>
<property name="class_kor_name">
<column name="CLASS_KOR_NAME"/>
</property>
<property name="class_eng_name">
<column name="CLASS_ENG_NAME"/>
</property>
<property name="class_cont">
<column name="CLASS_CONT"/>
</property>
<property name="item_grp_code">
<column name="ITEM_GRP_CODE"/>
</property>
<property name="regist_id">
<column name="REGIST_ID"/>
</property>
<property name="update_id">
<column name="UPDATE_ID"/>
</property>
<property name="trace_manage_target_yn">
<column name="TRACE_MANAGE_TARGET_YN"/>
</property>
<!-- regist_ts -->
<!--
<property name="regist_ts" >
<column name="regist_ts"/>
</property>
<property name="update_ts" >
<column name="update_ts"/>
</property>
-->
<property name="use_yn" >
<column name="USE_YN"/>
</property>
<property name="codeAge" insert="false" update="false">
<column name="code_age"/>
</property>
<!-- 코드 구분 (신코드, 구코드, 자료없음, etc.) -->
<many-to-one name="code_age" class="properties.item.SimpleItemCodeType"
lazy="false" not-found="ignore">
<column name="code_age"></column>
</many-to-one>
<!-- 추적관리대상여부 -->
<many-to-one name="traceability" class="properties.item.SimpleTraceability"
lazy="false" not-found="ignore">
<column name="TRACEABILITY"></column>
</many-to-one>
<!-- 사용여부 -->
<many-to-one name="isInUse" class="properties.SimpleIsInUse"
lazy="false" not-found="ignore">
<column name="IS_IN_USE"></column>
</many-to-one>
<!-- 현재 코드에 대한 구품목코드 -->
<!--
<many-to-one name="older_class_no" class="foreign.Mea_class_no"
lazy="false" not-found="ignore" insert="false" update="false" >
<column name="older_class_no"></column>
<column name="grade"></column>
</many-to-one>
-->
<!-- 이력현황 -->
<set name="history" cascade="all, persist, delete-orphan, delete"
fetch="select"
lazy="false" table="JUNC_ITEM_HISTORY">
<key >
<column name="mea_class_no"></column>
<column name="grade"></column>
</key>
<many-to-many not-found="ignore" class="properties.item.SimpleItemHistory"
column="history_id"
>
</many-to-many>
</set>
</class>
</hibernate-mapping>
编辑 我刚试过这个。
Session session = sessionFactory.getCurrentSession();
Mea_class_no found = readMeaClassNo(target);
System.out.println("getCurrentLockMode ? " + session.getCurrentLockMode(found));
session.delete(found);
System.out.println("isDirty ? " + session.isDirty());
我在控制台中看到了这一点。
getCurrentLockMode ? READ
isDirty ? true
但我不知道从这里做什么。
EDIT2 令我惊讶的是,添加
optimistic-lock="dirty"
到我的 hbm 文件,成功删除了一条记录,但它发出了一个奇怪的删除语句!
delete
from
MEA_CLASS_NO
where
mea_class_no=?
and grade=?
and mea_class_no = ?
and grade = ?
and grade = ?
and HIGHER_CLASS_NO = ?
and HIGHER_CLASS_GRADE = ?
and CLASS_LEVEL = ?
and CLASS_KOR_NAME = ?
and CLASS_ENG_NAME = ?
and CLASS_CONT = ?
and ITEM_GRP_CODE is null
and REGIST_ID is null
and UPDATE_ID is null
and TRACE_MANAGE_TARGET_YN = ?
and regist_ts = ?
and update_ts = ?
and USE_YN = ?
and code_age = ?
and code_age = ?
and TRACEABILITY = ?
and IS_IN_USE = ?
16:43:11,747 TRACE BasicBinder:84 - binding parameter [1] as [VARCHAR] - testtt
16:43:11,747 TRACE BasicBinder:84 - binding parameter [2] as [INTEGER] - 1
16:43:11,747 TRACE BasicBinder:84 - binding parameter [3] as [VARCHAR] - testtt
16:43:11,748 TRACE BasicBinder:84 - binding parameter [4] as [BIGINT] - 1
16:43:11,748 TRACE BasicBinder:84 - binding parameter [5] as [INTEGER] - 1
16:43:11,748 TRACE BasicBinder:84 - binding parameter [6] as [VARCHAR] - A06010
16:43:11,748 TRACE BasicBinder:84 - binding parameter [7] as [INTEGER] - 3
16:43:11,748 TRACE BasicBinder:84 - binding parameter [8] as [INTEGER] - 3
16:43:11,749 TRACE BasicBinder:84 - binding parameter [9] as [VARCHAR] - 테스트트
16:43:11,749 TRACE BasicBinder:84 - binding parameter [10] as [VARCHAR] - testtt
16:43:11,749 TRACE BasicBinder:84 - binding parameter [11] as [VARCHAR] - 테스트트
16:43:11,749 TRACE BasicBinder:84 - binding parameter [12] as [VARCHAR] - Y
16:43:11,750 TRACE BasicBinder:84 - binding parameter [13] as [TIMESTAMP] - 2013-11-15 15:56:24.226544
16:43:11,751 TRACE BasicBinder:84 - binding parameter [14] as [TIMESTAMP] - 2013-11-15 15:56:24.226544
16:43:11,751 TRACE BasicBinder:84 - binding parameter [15] as [VARCHAR] - Y
16:43:11,751 TRACE BasicBinder:84 - binding parameter [16] as [INTEGER] - 1
16:43:11,752 TRACE BasicBinder:84 - binding parameter [17] as [BIGINT] - 1
16:43:11,752 TRACE BasicBinder:84 - binding parameter [18] as [BIGINT] - 1
16:43:11,752 TRACE BasicBinder:84 - binding parameter [19] as [BIGINT] - 1
【问题讨论】:
看看***.com/a/11736653/1651233 @whoAmI,堆栈跟踪没有提到 StaleStateException。 stacktrace(这里和那里)都有这一行: org.hibernate.StaleStateException: Batch update returned unexpected row count from update [0];实际行数:0;预计:1 【参考方案1】:检查数据库模式中是否存在级联,导致每次从JUNC_ITEM_HISTORY
中删除引用记录时都会删除记录MEA_CLASS_NO
。或者在 SQLDeveloper 中尝试在一个事务中运行两个查询。如果级联存在,则应将其从数据库中删除并在 Hibernate 级别中声明。
【讨论】:
感谢 Alexey,但为了使问题更容易解决,我删除了关联。尽管如此,任何更新或删除语句都会失败。 你删除了什么?外键?它是否包含 ON DELETE CASCADE?您是否尝试过在 SQLDeveloper 中执行这两个查询?【参考方案2】:原来,它没有更新或删除的原因是类型不匹配。
由于某种奇怪的原因,表设计器将数字列声明为 varchar(1) 我正在将该 varchar 列映射到 POJO int 字段。
将字段类型更改为字符串后,问题就消失了。
【讨论】:
以上是关于Hibernate 删除记录惨遭失败的主要内容,如果未能解决你的问题,请参考以下文章
在 JPA/Hibernate 中使用 @OnetoMany 的实体中不存在时从数据库中删除子记录(Spring 引导应用程序)