JBoss在托管事务时提交事务

时间:2014-03-14 13:48:31

标签: java hibernate logging jboss

首先,我使用Eclipse,JBoss应用服务器和sql server数据库。我正在开发的项目是处理Java bean。我正在使用hibernate来创建和更新数据库。

我想要实现的目标:每次用户创建(持久化)“EntityClass”(见下文)时,我想在数据库的不同表中插入有关创建的信息。

我的(目前没有工作)解决方案:

我正在使用拦截器类拦截像这样的java Session bean中的方法;

@Interceptors(MyInterceptorClass.class)
public EntityClass createEntityClass(EntityClass e) {
    em.persist(e);
    return e;
}

我的InterceptorClass看起来像这样:

public class MyInterceptorClass{    

@AroundInvoke
public Object logMethod(InvocationContext iCtx) throws Exception {
    Logger logger = new Logger();
    logger.setAction("create");
    Session session = HibernateUtil.getSessionFactory().openSession();          
    session.beginTransaction();
    session.save(logger);
    session.getTransaction().commit()
    return iCtx.proceed();
    }

我的Logger类是一个实体java bean,当我的拦截器拦截目标方法时,我希望将其保存到数据库中,如您所见。记录器代码:

@Entity
@Table(name = "auditlog")
public class Logger implements Serializable {
    private int auditLogId; //auto-increment in DB
    private String action;
    ...
    //setters and getters with proper mapping to the related database table
}

正如你现在可能已经想到的那样,这个投标人抛出了一个例外,说我在托管交易期间无法提交。如果没有开始新的交易,我有什么方法可以做到这一点吗?

我试过了:

*在记录器类

上将事务属性更改为REQUIRES_NEW

*使用会话bean @PreDestroy回调方法

保留logger对象

我愿意就如何解决这个问题提出建议。

2 个答案:

答案 0 :(得分:1)

我通过使用Hibernate Envers进行实体审核来解决这个问题。

http://docs.jboss.org/envers/docs/index.html#quickstart

向用户3360944致信,向我暗示正确的方向。

答案 1 :(得分:0)

Hibernate是对的,你不能在托管事务中调用commit。将事件的日志记录与事件本身联系起来也是一个坏主意,因为永远不会告知您完全回滚的故障。

我建议使用日志记录功能的队列实现或调用Web服务来执行日志记录功能。那些可以在当前功能范围之外操作。

一个功能齐全的方法还可以捕获ctx.proceed()中抛出的任何异常并记录失败,这可能比成功更有趣。