Я совершенно не знаком с Spring, JPA и Hibernate, поэтому извиняюсь, если я не правильно ставил этот вопрос.
Мне было предоставлено приложение, использующее эти фреймворки с несколькими проблемами производительности.
Я сделал многочисленные поиски безрезультатно - возможно, из-за моей неспособности правильно сформулировать мой вопрос.
Сценарий (в двух словах) заключается в том, что когда один оператор sql выполняется через EntityManager, он, в свою очередь, вызывает связанный запрос в строке набора результатов. В моем случае оператор sql может вызвать сотни (и в некоторых случаях тысяч) связанных операторов sql для вызова - убийство нашего сервера.
Надуманным примером может быть:
public class Job
{
public long jobId;
public String name;
public List<Transaction> transactions;
}
public class Transaction
{
public long transactionId
public List<Stock> stocks;
}
public class Stock
{
public long stockId;
public String name;
}
The code uses a statement like:
String jpaQuery = "select distinct j from Job j where j.jobId = :jobId order by name asc";
Query query = entityManager.createQuery(jpaQuery);
//set parameters...
//This will return a List<Job>, containing lists of Transaction and Stock objects
return query.getResultList();
Выполнение этого одиночного оператора sql приводит к выполнению нескольких выполняемых sql-операторов (которые можно просмотреть в консоли журнала tomcat/eclipse), поэтому они вызываются кодом/каркасом. EntityManager не был расширен, поэтому структура выполняет работу.
Теперь мой вопрос - спасибо за прочтение этого...
В Spring, JPA и Hibernate, каким будет лучший способ приблизиться к этому, так что один вызов в базу данных возвращает требуемые объекты без нескольких запросов к базе данных?
Моя мысль о подходе заключается в том, чтобы один оператор sql вызывал хранимую процедуру, которая могла либо возвращать несколько наборов результатов, либо только один набор результатов, содержащий данные для всех связанных объектов, и иметь структуру для остальных (создать экземпляр соответствующих объектов).
Я не знаю, как это сделать в среде Spring/JPA/Hibernate. Может ли кто-нибудь указать мне на ресурсы, которые дадут мне примеры/идеи о том, как подойти к этому? Или ключевые слова для поиска?
Версия: Spring: 3.0.6.Отмена Hibernate: 3.5.0-Beta-2
Большое спасибо Стив
Во-первых, это не оператор SQL, это оператор JPQL, который представляет собой огромную разницу (не синтаксис, а логический мудрый).
Во-вторых, причиной множественных операторов SQL является "один-ко-многим" отношениям с заданием на транзакцию на акции (это называется проблемой N + 1). В зависимости от вашего варианта использования вы можете изменить отношения к ленивой загрузке. Это означает, что они загружаются только тогда, когда вам нужны объекты. Однако это может вызвать другие проблемы, если они не обрабатываются правильно. Вы также можете попытаться использовать функцию "Взятие". Это создаст единый запрос с соединением, вместо этого выдает один подсегмент для каждого элемента в коллекции.
@OneToOne
и @OneToMany
в нескольких местах) явно (каждая отдельно) загружаются с помощью SQL-запроса с помощью WHERE
. Интересно, как я могу избавиться от этого утверждения WHERE? Я знаю FetchMode.LAZY
но это только задержит проблему, пока ваша пользовательская база не увеличится. В настоящее время я использую по умолчанию ( EAGER
). Любой способ сказать JPA (только javax.persistence.*
Используется здесь), чтобы получить всю таблицу? ОЗУ не проблема, но производительность может быть.