Hibernate缓存问题

来源:互联网 发布:张爱玲老公 知乎 编辑:程序博客网 时间:2024/06/07 05:44

VOP门户-》客户服务-》工单处理-》VOPMNG_S报错


现象:

2016-03-25 17:08:48,230 (JDBCExceptionReporter.java:100) WARN  - SQL Error: 14400, SQLState: 72000
2016-03-25 17:08:48,231 (JDBCExceptionReporter.java:101) ERROR - ORA-14400: inserted partition key does not map to any partition


2016-03-25 17:08:48,231 (JDBCExceptionReporter.java:100) WARN  - SQL Error: 14400, SQLState: 72000
2016-03-25 17:08:48,232 (JDBCExceptionReporter.java:101) ERROR - ORA-14400: inserted partition key does not map to any partition


2016-03-25 17:08:48,236 (AbstractFlushingEventListener.java:324) ERROR - Could not synchronize database state with session
org.hibernate.QueryTimeoutException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:124)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:114)
at org.hibernate.jdbc.AbstractBatcher.prepareStatement(AbstractBatcher.java:109)
at org.hibernate.jdbc.AbstractBatcher.prepareBatchStatement(AbstractBatcher.java:244)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2395)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2858)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:79)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:260)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:179)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:51)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
at com.tydic.commons.HibernateDaoHelper.delete(HibernateDaoHelper.java:98)
at com.tydic.commons.AbstractDaoSupport.delete(AbstractDaoSupport.java:155)
at com.tydic.vop.complaint.service.CplntWorkorderService.feedBackComplaint(CplntWorkorderService.java:322)
at com.tydic.vop.complaint.service.CplntWorkorderService.feedBackOrReplyComplaint(CplntWorkorderService.java:248)
at com.tydic.vop.complaint.service.CplntWorkorderService$$FastClassByCGLIB$$186e2668.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:701)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:634)
at com.tydic.vop.complaint.service.CplntWorkorderService$$EnhancerByCGLIB$$95f668aa.feedBackOrReplyComplaint(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.tydic.commun.mng.VOPServiceSkeleton.service(VOPServiceSkeleton.java:47)
at com.tydic.commun.mng.VOPServiceMessageReceiverInOut.invokeBusinessLogic(VOPServiceMessageReceiverInOut.java:51)
at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:114)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:173)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:173)
at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:144)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)


跟踪到  at com.tydic.vop.complaint.service.CplntWorkorderService.feedBackComplaint(CplntWorkorderService.java:322) -》

CplntWorkorderService.java 内的 feedBackComplaint方法 (322行)-》

322行: todoTaskDao.delete(todoTasks.get(0));


进入delete方法内部,

AbstractDaoSupport.java ->

publicvoid delete(To) {

daoHelper.delete(o, getHibernateTemplate());

->

public class HibernateDaoHelper {

/**

* 删除对象

*/

public void delete(Object o, HibernateTemplatehibernateTemplate) {

hibernateTemplate.getSessionFactory().getCurrentSession().setFlushMode(FlushMode.AUTO);

hibernateTemplate.delete(o);

hibernateTemplate.getSessionFactory().getCurrentSession().flush();

}


执行delete 怎么报

2016-03-25 17:08:48,232 (JDBCExceptionReporter.java:101) ERROR - ORA-14400: inserted partition key does not map to any partition
这样的错误??


推测:

1. delete 的 where 条件 没有对应分区, 可能会报找不到分区异常。

2. 对delete 进行代理?切面编程? 进行额外的对数据库操作导致找不到分区异常。


观察 执行delete的对象 与 delete表: todo_task

2016-03-25 17:08:48,141 (CplntWorkorderService.java:321) INFO  - todoTasks.get(0).getUpdTime(): 2016-03-24 21:45:21.0

分区条件 2016-03-24 21:45:21.0    &&  表todo_task分区到 2017年,足够

排除1. 


2.spring_applicationContext.xml

<beanid="vopSessionFactory"


->

<propertyname="eventListeners">


<map>

<entry>

<key>

<value>post-delete</value>

</key>

<refbean="deleteListener"/>

</entry>


...

...

<beanid="deleteListener"class="com.tydic.hbm.listener.DeleteEventListener"/>

<beanid="updateListener"class="com.tydic.hbm.listener.UpdateEventListener"/>

<beanid="saveListener"class="com.tydic.hbm.listener.SaveEventListener"/>

<beanid="collectionUpdListener"class="com.tydic.hbm.listener.UpdateCollectionEventListner"/>


进入 DeleteEventListener.java 
 publicvoid onPostDelete(PostDeleteEventevent) {

...

savePostDelLog(t.getName(), getAccessRecordId(id),chgValue);

...

跟进入 UlogCfgUtil.java

public class UlogCfgUtil {

private static final Log log = LogFactory.getLog(UlogCfgUtil.class);

private static ThreadLocal<String> loginId = new ThreadLocal<String>();

public void savePostDelLog(String tabName,StringupdDescribe,List<ValuePair>chgValues){

if(log.isDebugEnabled())log.debug("保存删除日志:" +tabName);

save("D",tabName,updDescribe,chgValues);

}

...

private void save(String oprType,String tabName,String recdId,List<ValuePair> chgValues){

log.info("begin 记录日志 about "+tabName);

DataSource ds = DbcpUtils.getVopLogDS();

Connection conn =null;

PreparedStatement stmt = null;

try{

conn = ds.getConnection();

conn.setAutoCommit(false);

stmt =conn.prepareStatement("insert into L_busi_table_log(L_busi_table_log_id,L_login_log_id,access_busi_table,access_record_id,table_opr_type,access_time)" +

" values(L_busi_table_log_idseq.nextval,?,?,?,?,sysdate)");

stmt.setString(1,loginId.get());

stmt.setString(2,tabName);

stmt.setString(3,recdId);



...
果然有额外插入日志 L_busi_table_log    查看分区, 不够, 建上




再次测试, 还有那个报错!!

ERROR - ORA-14400: inserted partition key does not map to any partition

通过观察整个流程,

...

cplntWorkorderDao.saveComplaintFeedback(complaintFeedback);

...

发现有对多个表操作

逐个检查所有表, 发现 cplnt_Workorder 没分区,建上,


再测, 

通过了??!!!!

WHY ?????


发现:

/**

* 删除对象

*/

public void delete(Object o, HibernateTemplatehibernateTemplate) {

hibernateTemplate.getSessionFactory().getCurrentSession().setFlushMode(FlushMode.AUTO);

hibernateTemplate.delete(o);

hibernateTemplate.getSessionFactory().getCurrentSession().flush();

}


hibernateTemplate.getSessionFactory().getCurrentSession().flush();

这些数据库操作都在一个hibernate事务内,而前面的save 操作只是保存到 hibernate的缓存内, 没有刷新到数据库, 

而在这delete 时,flush 所有缓存, 其中包含前面的save操作, 导致 ORA-14400: inserted partition key does not map to any partition


查hibernate 缓存资料, 确实如此。



参考资料:http://www.cnblogs.com/yanbincn/archive/2012/05/31/2529293.html

缓存、刷新、flush
针对昨天同事遇到的hibernate的问题。算是hibernate最基本的东西。具了解,这个问题很多人遇到过,也很常见,却遇到了还经常会懵了。
 
为了加深印象,知其然,知其所以然。
 
之后单纯用原始的Hibernate框架做了一些验证,并且打开执行SQL打印输出台的,得出的结论:
 
前提是在同一事务中间:
 
1、利用sql语句, session.createSQLQuery(sql).executeUpdate();进行插入,输出台打印出sql插入语句; 再利用sql语句,进行session.createSQLQuery(sql).uniqueResult(); 也会打印SQL查询语句,没有问题,可以查询到数据。
 
2、利用hibernate封装操作, session.save(entity); 进行插入,输出台并没有打印出插入的SQL语句, 再利用 session.get(entity,id);方法做查询 ;也没有打印出SQL查询语句,但是是可以查询到数据的。到执行事务提交语句时,插入的SQL语句被打印出来
 
3、利用hibernate的session.save(entity); 进行插入,再利用《HQL》语句进行查询,效果同上面第二点。
 
4、利用hibernate的session.save(entity); 进行插入,输出台并没有打印出插入的SQL语句。 再利用sql语句,进行session.createSQLQuery(sql).uniqueResult(); 会打印SQL查询语句。问题出现了,查询不到任何数据。这种情况下利用session.flush()方法,在查询之前执行到flush()方法,输出台会打印出插入的SQL语句。 再进行查询就有数据。







0 0
原创粉丝点击