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()的调用大约需要140ms ……相当令人费解。 数据库对其他查询执行得很好,包括一些处理程序中的这个(我怀疑它不是第一个查询运行时)。

JProfiler建议每次调用时,都会向数据库发送四个查询(不一定按此顺序):

 1)[5ms]选择用户...(实际查询)

 2)[7ms] SHOW COLLATION

 3)[14ms] / * mysql-connector-java-5.1.7(修订版:$ {svn.Revision})* / SELECT @@ session.auto_increment_increment

 4)[70ms] / * mysql-connector-java-5.1.7(修订版:$ {svn.Revision})* / SHOW VARIABLES WHERE Variable_name ='language'或Variable_name ='net_write_timeout'或Variable_name ='interactive_timeout'或Variable_name ='wait_timeout'或Variable_name ='character_set_client'或Variable_name ='character_set_connection'或Variable_name ='character_set'或Variable_name ='character_set_server'或Variable_name ='tx_isolation'或Variable_name ='transaction_isolation'或Variable_name ='character_set_results'或Variable_name =' timezone'OR Variable_name ='time_zone'OR Variable_name ='system_time_zone'OR Variable_name ='lower_case_table_names'ORV Variable_name ='max_allowed_pa​​cket'ORVore_name ='net_buffer_length'ORVore_name ='sql_mode'ORVore_name ='query_cache_type'OR Variable_name ='query_cache_size' OR Variable_name ='init_connect'

很明显,实际的查询根本没有时间,大部分时间都花在第四个上。 我该怎么办? 它不会显示在hibernate日志输出中,只会显示第一个实际查询。 顺便说一下,在调用getJpaTemplate() 之后花了所有时间 – 实际上是在jpa.find()方法中。

有任何想法吗?

更新:我已经知道它是hibernate多次与数据库进行某种初始连接,因为其他人发布了同一组查询( http://ondra.zizka.cz/stranky/programovani/java/hibernate_netbeans_howto_tutorial .texy )。 为什么hibernate会重复进行初始连接,不是使用连接池 – 我该如何检查?

我已经解决了。 我有一个非汇集的数据源:

  

来自Javadoc: http : //static.springsource.org/spring/docs/2.0.x/api/org/springframework/jdbc/datasource/DriverManagerDataSource.html

简单实现标准JDBC DataSource接口,通过bean属性配置普通的旧JDBC DriverManager,并从每个getConnection调用返回一个新的Connection。 注意:此类不是实际的连接池; 它实际上并没有池连接。 它只是简单替代完整的连接池,实现相同的标准接口,但每次调用都会创建新的连接。

所以我现在用以下代替:

       

我不得不投入c3p0-0.9.1.2.jar,因为它使用了该连接池。