У меня есть странная проблема, когда Hibernate запускает больше запросов, чем я просил, и не вижу необходимости.Hibernate отправки лишних запросов в базу данных
Вот мой контроллер:
@Autowired UserService users;
@RequestMapping("/test")
@ResponseBody
public String test() {
User user = users.findUser(1L);
return "Found user: "+user.getEmail();
}
Вот UserService:
@Component
public class UserService {
@javax.persistence.PersistenceUnit private EntityManagerFactory emf;
private JpaTemplate getJpaTemplate() {
return new JpaTemplate(emf);
}
public User findUser(long id) {
long start = System.currentTimeMillis();
JpaTemplate jpaTemplate = getJpaTemplate();
User user = jpaTemplate.find(User.class, id);
System.out.println(System.currentTimeMillis() - start);
return user;
}
}
Вызов findUser() занимает около 140мс ... Скорее озадачивает. База данных отлично подходит для других запросов, в том числе и для некоторых обработчиков (я подозреваю, что это не первый запуск запроса).
JProfiler предполагает, что каждый раз, когда она называется, четыре запросы отправляются в базу данных (не обязательно в таком порядке):
1) [5ms] select user... (the actual query) 2) [7ms] SHOW COLLATION 3) [14ms] /* mysql-connector-java-5.1.7 (Revision: ${svn.Revision}) */SELECT @@session.auto_increment_increment 4) [70ms] /* mysql-connector-java-5.1.7 (Revision: ${svn.Revision}) */SHOW VARIABLES WHERE Variable_name ='language' OR Variable_name = 'net_write_timeout' OR Variable_name = 'interactive_timeout' OR Variable_name = 'wait_timeout' OR Variable_name = 'character_set_client' OR Variable_name = 'character_set_connection' OR Variable_name = 'character_set' OR Variable_name = 'character_set_server' OR Variable_name = 'tx_isolation' OR Variable_name = 'transaction_isolation' OR Variable_name = 'character_set_results' OR Variable_name = 'timezone' OR Variable_name = 'time_zone' OR Variable_name = 'system_time_zone' OR Variable_name = 'lower_case_table_names' OR Variable_name = 'max_allowed_packet' OR Variable_name = 'net_buffer_length' OR Variable_name = 'sql_mode' OR Variable_name = 'query_cache_type' OR Variable_name = 'query_cache_size' OR Variable_name = 'init_connect'
Его ясно, что фактический запрос не принимает вообще никакого времени, и большинство время тратится на этот четвертый. Что я могу сделать по этому поводу? Он не отображается в выводе журнала гибернации, а только первый, фактический запрос. Кстати, все время проводится после вызов getJpaTemplate() - фактически, в методе jpa.find().
Любые идеи?
ОБНОВЛЕНИЕ: Я разработал, что спящий режим выполняет какое-то первоначальное подключение к базе данных несколько раз, поскольку кто-то еще отправил один и тот же набор запросов (http://ondra.zizka.cz/stranky/programovani/java/hibernate_netbeans_howto_tutorial.texy). Почему hibernate делает свое первоначальное соединение повторно, не использует ли пул соединений - как я могу проверить?
Вы должны отредактировать свой вопрос и правильно отформатировать код. Выделите его в редакторе и нажмите кнопку «101010» на панели инструментов. –
Я знаю, что я очень старался это сделать, но поскольку я использую вкладки, этот сайт превращал их в пробелы, и он был потерян, когда я спасал - хотя это выглядело отлично в предварительном просмотре. Я должен подать отчет об ошибке, если они не знают! – gubby