subes
subes

Reputation: 1832

autocommit and @Transactional and Cascading with spring, jpa and hibernate

what I would like to accomplish is the following:

  1. have autocommit enabled so per default all queries get commited
  2. if there is a @Transactional on a method, it overrides the autocommit and encloses all queries into a single transaction, thus overriding the autocommit
  3. if there is a @Transactional method that calls other @Transactional annotated methods, the outer most annotation should override the inner annotaions and create a larger transaction, thus annotations also override eachother

I am currently still learning about spring-orm and couldn't find documentation about this and don't have a test project for this yet.

So my questions are:

--EDIT--

I have the following test-setup:

@javax.persistence.Entity
public class Entity {
  @Id
  @GeneratedValue
  private Integer id;
  private String name;
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
}

@Repository
public class Dao {
  @PersistenceContext
  private EntityManager em;
  public void insert(Entity ent) {
    em.persist(ent);
  }
  @SuppressWarnings("unchecked")
  public List<Entity> selectAll() {
    List<Entity> ents = em.createQuery("select e from " + Entity.class.getName() + " e").getResultList();
    return ents;
  }
}

If I have it like this, even with autocommit enabled in hibernate, the insert method does nothing. I have to add @Transactional to the insert or the method calling insert for it to work...

Is there a way to make @Transactional completely optional?

Upvotes: 2

Views: 17867

Answers (1)

Bozho
Bozho

Reputation: 597324

  • you can't have queries without an active transaction in hibernate
  • @Transactional has a propagation attribute, which identifies the transaction behaviour when new methods are called. The default is REQUIRED, which is what you want. Here you can find a graphical presentation of the concept.
  • you can omit using @Transactional if you set-up your transactional methods with aop, like this:

    <aop:config>
        <aop:pointcut id="serviceMethods"
            expression="execution(* com.company.product.service..*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceMethods" />
    </aop:config>
    
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>
    

    That makes all public methods in the service package transactional.

Also, feel free to read the entire chapter on spring transactions.

Upvotes: 1

Related Questions