I have an application built on Spring. I let the Spring do the all @Transactional
magic and everything works fine as long as I operate on my entities that are mapped to Java objects.
However, when I want to do some custom job on a table that is not mapped to any of my Java entities, I'm stuck. Some time ago, I found a solution to execute a custom query like this:
// em is instance of EntityManager
em.getTransaction().begin();
Statement st = em.unwrap(Connection.class).createStatement();
ResultSet rs = st.executeQuery("SELECT custom FROM my_data");
em.getTransaction().commit();
When I try this with the entity manager injected from Spring with the @PersistenceContext
annotation, I receive almost obvious exception:
java.lang.IllegalStateException:
Not allowed to create transaction on shared EntityManager -
use Spring transactions or EJB CMT instead
I finally managed to extract non-shared Entity Manager like this:
@Inject
public void myCustomSqlExecutor(EntityManagerFactory emf){
EntityManager em = emf.createEntityManager();
// the em.unwrap(...) stuff from above works fine here
}
Nevertheless, I find this solution neither comfortable nor elegant. I just wonder if there is any other way to run custom SQL queries in this Spring-transactional-driven environment?
For those who are curious - this problem appeared when I tried to create user accounts in my application and in the related forum at once - I did not want the forum's users table to be mapped to any of my Java entities.