Во-первых, извините, если я прошу очевидного или если вопрос принципиально немой по своей природе.JPA создайте запрос только один раз
Более академический вопрос должен знать, могу ли я создать запрос JPA (названный или любой другой), который охватывает или не зависит от EntityManager
. В принципе, Подготовьте один раз подряд всегда. Я понимаю, что мы можем получить экземпляр запроса только из методов createXXXQuery
объектов управления enitity, но все-таки есть ли другой способ?
Это то, что я пытаюсь сделать,
public class MyRepo {
@PersistenceContext
private EntityManager em;
private Query aQueryIntentedtoBePreparedOnlyOnce;
@PostConstruct
public void prepareMyQuery(){
aQueryIntentedtoBePreparedOnlyOnce = em.createQuery("...."); // Query with positional params
}
public void executeMyQuery(){
aQueryIntentedtoBePreparedOnlyOnce.getResultList();
}
}
Это выполняет совершенно в первый раз. Но во второй раз он говорит, что «Entity Manager закрыт». Я понимаю, что это связано с тем, что EM - это транзакция.
Этот EM управляется контейнером (JTA - Spring), поэтому я не могу распространять его на транзакции. И использование Session beans не является вариантом. Итак, есть ли способ создать этот запрос только один раз?
PS: Где находятся именованные запросы и кеширование запросов? с Именованными запросами я все еще, кажется, делаю createNamedQuery
каждый раз. И что такое план кеша запросов, есть ли хорошие документы для него?
Еще один вопрос, почему запросы, созданные только на EM или в соединении (JDBC)? Разве мне не нужно знать, с какой БД я разговариваю, чтобы подготовить запрос? Это так, что никогда нельзя выполнить одно без правильной связи?
Вы не можете. С простой спящей вы можете использовать 'DetachedCriteria', но в конце концов все равно должен стать экземпляром« Criteria »для выполнения, и для этого вам все еще нужен« Session »(или в терминах JPA« EntityManager »). Но зачем вам это делать? Вы не получите какой-либо/большой производительности (он будет использовать больше памяти), и фактический запрос (если настроен) кэшируется вашим драйвером JDBC. –
@M. Deinum Мне не нужно это делать, просто интересно, не хватает ли я чего-то. И почему он потребляет больше памяти? вызвать запрос является членом моего объекта репо? Не меняется ли SQL с параметрами, какие использует JDBC-диск, кэшированный SQL? – anchreg
Нет. Поскольку «PreparedStatement» кэшируется не с помощью связанного параметра. У вас больше объектов в памяти, следовательно, больше памяти. Теперь у вас очень короткий объект, который довольно быстро удаляется из памяти. –