简体   繁体   中英

JBoss Commit a transaction while a managed transaction

First up, im using Eclipse, JBoss application server and a sql server database. The project im working on is handeling Java beans. I'm using hibernate to create and update the database.

What I want to achieve: Everytime a user creates(persists) the "EntityClass" (see below) I want to insert information regarding the creation in a diffrent table in the database.

My (not currently working) solution:

I'm using an interceptor class to intercept a method in a java Session bean like this;

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

My InterceptorClass looks like this:

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();
    }

my Logger class is an entity java bean that I want to persist to the database when my interceptor intercepts the target method as you can see. Code for Logger:

@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
}

As you might have figured out by now, the cointainer throws me an exception saying that I cannot commit during a managed transaction. Is there any way for me to do this without starting a new transaction?

I've tried:

*Changing the transaction attribute to REQUIRES_NEW on the logger class

*Persist the logger object with the session beans @PreDestroy callback method

I am open for suggestions on how to circle this problem.

I solved this problem by using Hibernate Envers for entity auditing.

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

Creds to user3360944 for hinting me in the right direction.

Hibernate is right, you cannot call commit during a managed transaction. Also it is a bad idea to tie the logging of an event with the event itself, because you will never be advised of failures that are rolled back in their entirety.

I would suggest using either a queue implementation of the logging function or calling a web service to to execute the logging function. Those can operate outside of the scope of the current function.

A full-featured approach would also catch any exception thrown in ctx.proceed() and log the failure which may be more interesting than the successes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM