做了一个hibernate的listener,implements了SaveOrUpdateEventListener ,这个类会监控所有调用saveorupdate方法,然后在之前插入我的业务逻辑,如设置创建用户,公司等通用信息。平时也运行正常,但是偶尔会遇到没有插入用户,公司信息的情况,大概10w分之一的概率吧,代码如下:
@SuppressWarnings("serial") public class AuditListener implements SaveOrUpdateEventListener { private static Logger logger = LoggerFactory.getLogger(AuditListener.class); public void onSaveOrUpdate(SaveOrUpdateEvent event) throws HibernateException { Object object = event.getObject(); if (object instanceof AuditableEntity && SpringSecurityUtils.getCurrentCustomUser() != null) { AuditableEntity entity = (AuditableEntity) object; String loginName = SpringSecurityUtils.getCurrentUserName(); // Long id = getEntityId(entity); Long id = entity.getMainid(); if (id == null) { // 创建新对象 entity.setRecAddTime(new Date()); entity.setRecLoginUser(loginName); entity.setCompanyId(SpringSecurityUtils.getCurrentCustomUser() .getCompanyId()); entity.setSystemId(SpringSecurityUtils.getCurrentCustomUser() .getSystemId()); logger.warn("{}对象(ID:{}) 被 {} 在 {} 创建", new Object[] { object.getClass().toString(), id, loginName, new Date() }); } else { // 修改旧对象 entity.setRecUpdateTime(new Date()); entity.setRecModifyUser(loginName); logger.warn("{}对象(ID:{}) 被 {} 在 {} 修改", new Object[] { object.getClass().toString(), id, loginName, new Date() }); } } } } public class SpringSecurityUtils { /** * 取得当前用户的User实例, 如果当前用户未登录则返回null. */ public static CustomerUserDetails getCurrentCustomUser() { Authentication authentication = getAuthentication(); if (authentication != null && authentication.getPrincipal() != null && !authentication.getPrincipal().equals("anonymousUser")) return (CustomerUserDetails) authentication.getPrincipal(); return null; } /** * 取得Authentication, 如当前SecurityContext为空时返回null. */ private static Authentication getAuthentication() { SecurityContext context = SecurityContextHolder.getContext(); if (context != null) return context.getAuthentication(); return null; } }
我没有办法验证重复这个过程,hibernate应该不会出问题,只是猜测可能的情况是,用户在调用saveorupdate方法后,由于数据库延时,而导致卡住,但是这个时候,刚好session过期了,通过SecurityContextHolder无法获得用户信息,从而导致了设置用户,公司这个业务的失败,大家能不能帮我分析一下我的猜测是否正确,如何验证,又如何解决。部署在jboss5.01GA下没有这样的问题,但是月前部署在tomcat6.0.18下开始出现问题,会和tomcat有关吗,拿不到session?