Configuring Hibernate transactions only with Jersey API annotations

2

I want to use something similar to org.springframework.transaction.annotation.Transactional of Spring that sets up a Transaction only using only the Jersey API. Something similar to the code below:

@Resource
private SessionFactory factory;

private Class<E> entity;

private String tableName;

public DataProvider(Class e) {
    this.entity = e;
    this.tableName = entity.getAnnotation(Table.class).name();
}

@Transactional(readOnly = true)
public E get(final Long ID) {
    return (E)factory.getCurrentSession().get(entity, ID);
}

@Transactional(readOnly = true)
public List<E> getAll() {
    Session s = factory.getCurrentSession();
    return s.createQuery("FROM " + tableName ).list();
}

Is it possible?

    
asked by anonymous 17.02.2014 / 20:36

2 answers

3

No, it is not possible to do with Hibernate transaction control Jersey.

Understand that Jersey is made for REST communication and has nothing to do with hibernate transaction.

You could use CDI to perform transaction control, but nothing to do with Jersey.

With CDI you need to create an Interceptor:

@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
@InterceptorBinding
public @interface Transaction {
    boolean readOnly() default true;
}

And then you would create your interceptor as:

@Interceptor @Transaction(readOnly = false)
public class MethodWithTransaction {

    @Inject
    private EntityManager entityManager;

    @AroundInvoke
    public Object manageTransaction(InvocationContext context) throws Exception{
        EntityTransaction transaction = null;
        try{
            transaction = entityManager.getTransaction();
            transaction.begin();
            Object methodResult = context.proceed();
            transaction.commit();
            return methodResult;
        } catch (Exception ex){
            if(transaction != null && transaction.isActive()){
                transaction.rollback();
            }

            throw ex;
        }finally {
            entityManager.close();
        }
    }
}

To use you would apply as:

@Transaction(readOnly = false)
public void fazAlgo(){
    //
}

The only difference is that you will need to create an interceptor for when readOnly is true.

    
17.02.2014 / 21:02
2

If you are using an application server such as Wildfly, you can also make your service an EJB Stateless (add @Stateless at the top of the class), and all REST methods are automatically involved in a transaction.

If you're not using it, why not? By who and what it looks like, you will end up doing a manual integration that is already ready for use on "complete" Java EE servers ...

    
18.02.2014 / 15:00