У меня есть приложение, построенное на Spring. Я позволяю Spring делать всю магию @Transactional
, и все работает нормально, пока я работаю со своими сущностями, которые сопоставлены с объектами Java.
Однако, когда я хочу выполнить какую-то пользовательскую работу над таблицей, которая не сопоставлена ни с одной из моих сущностей Java, я застреваю. Некоторое время назад я нашел решение для выполнения пользовательского запроса, подобного этому:
// 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();
Когда я пытаюсь сделать это с менеджером сущностей, внедренным из Spring с аннотацией @PersistenceContext
, я получаю почти очевидное исключение:
java.lang.IllegalStateException:
Not allowed to create transaction on shared EntityManager -
use Spring transactions or EJB CMT instead
Наконец-то мне удалось извлечь неразделяемый Entity Manager следующим образом:
@Inject
public void myCustomSqlExecutor(EntityManagerFactory emf){
EntityManager em = emf.createEntityManager();
// the em.unwrap(...) stuff from above works fine here
}
Тем не менее, я не нахожу это решение ни удобным, ни элегантным. Мне просто интересно, есть ли другой способ запуска пользовательских SQL-запросов в этой среде, управляемой транзакциями Spring?
Для тех, кому любопытно - эта проблема возникла, когда я попытался создать учетные записи пользователей в своем приложении и на соответствующем форуме одновременно - я не хотел, чтобы таблица пользователей форума была сопоставлена ни с одной из моих Java-сущностей.