论坛首页 Java企业应用论坛

hibernate的SaveOrUpdateEventListener和spring的SecurityContextHolder的问题

浏览 2715 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-03-21  
hibernate 版本是3.6,springSecurity版本是3.0.5,spring版本是3.0.6,问题是
做了一个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无法获得用户信息,从而导致了设置用户,公司这个业务的失败,大家能不能帮我分析一下我的猜测是否正确,如何验证,又如何解决。
   发表时间:2012-04-04  
用一个通用的 EntityListener 就解决了,为什么要自己去掏古 Hibernate 的EnventListener。
0 请登录后投票
   发表时间:2012-04-04  
应该跟hibernate没关系,是SpringSecurityUtils没有取到用户信息导致的。而且你用的这个API应该是从threadlocal里面取值的,和当前线程有关。
0 请登录后投票
   发表时间:2012-04-10  
这个 还真没有遇到过
0 请登录后投票
   发表时间:2012-04-11  
的确和hibernate关系不大,springsecurity的确会把user信息注入当前线程,但不知道为什么会有这种不稳定的情况,这个低概率的事件如何监控调试会编辑好。
0 请登录后投票
   发表时间:2012-04-11  
原来是部署在jboss5GA下,好像还比较稳定,但是部署在tomcat6.0.18后,不太稳定,会不会和这个有关。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics