1

So I run into the 'No EntityManager with actual transaction available' problem, and thanks to that I realized that Spring is executing my SELECT queries without transactions.

Since some people warn against this practice (see here and here), how do I tell Spring to always use transactions?

EDIT

Judging from the answers that I got so far, I think that my question was not clear enough. So I don't have the 'No EntityManager with actual transaction available' anymore. I fixed that, but when I did have the problem, it was only for persist and merge operations, things like find were working, so that made me realize that Spring is only creating transactions for write operations. What I want now, is to force it to also create transactions for read-only operations.

Community
  • 1
  • 1
user4408343
  • 541
  • 5
  • 9

2 Answers2

0

I assume you have an web application: An other solution, would been using the OpenEntityManagerInViewFilter

From its JavaDoc:

This filter makes JPA EntityManagers available via the current thread, which will be autodetected by transaction managers. It is suitable for service layer transactions via TransactionManager or JtaTransactionManager as well as for non-transactional read-only execution.

So just add this lines to your web.xml:

<filter>
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
    <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
Ralph
  • 118,862
  • 56
  • 287
  • 383
  • I want to keep the transaction granularity at DAO level. Furthermore, I'm not looking for a solution to the `no transaction available` problem, but to force Spring to use transactions with `SELECT` queries. – user4408343 Jan 26 '16 at 11:45
  • You need to put ONE! `@Transactional` annotation arround the code that execute every sql-query. And pay attention to layzloading. - So if you use lazy loading and want to have every query in the same transaction, then attaching the `@Transactional` only at the DAO layer will likly not work. – Ralph Jan 26 '16 at 12:23
  • Thanks, but my DAO classes are annotated with `@Transactional`. I don't want lazy loading, that's not the issue. The issue is that the no transaction available made me realize that Spring is not creating transactions for `SELECT` queries, and I want to force it to create them. Please see my edit – user4408343 Jan 26 '16 at 14:41
0

If your code code contains a @Transactional and there is no transation open, It maybe means that you lack a TransactionManager you have to declare it like this :

<!-- Enables declarative transaction management with @Transactional annotations -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

(change the transactionManager Class according to your persistence technology here is for hibernate 3)

jpprade
  • 3,497
  • 3
  • 45
  • 58
  • So what make you think that your select is executed without transaction ? – jpprade Jan 26 '16 at 14:59
  • That I was getting that `No Entity Manager...` error only for `persist` and `merge`, not for `find`. I could happily get results from `SELECT` queries. – user4408343 Jan 26 '16 at 15:27