3

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は、呼び出されるたびに、4つのクエリがデータベースに送信されることを提案しています(必ずしもこの順序である必要はありません)。

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' 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_pa​​cket'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 '

実際のクエリにはまったく時間がかからず、ほとんどの時間はその4番目のクエリに費やされていることは明らかです。これについて私は何ができますか?Hibernateログ出力には表示されず、最初の実際のクエリのみが表示されます。ちなみに、 getJpaTemplate()の呼び出し、つまり実際にはjpa.find()メソッドですべての時間が費やされます。

何か案は?

更新:他の誰かが同じクエリのセットを投稿したため、データベースへのある種の初期接続を複数回行うのは休止状態であることがわかりました(http://ondra.zizka.cz/stranky/programovani/java/hibernate_netbeans_howto_tutorial .texy)。hibernateが最初の接続を繰り返し行うのはなぜですか?接続プールを使用していません-どうすれば確認できますか?

4

1 に答える 1

5

私はそれを解決しました。プールされていないデータソースがありました:

<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

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

標準のJDBCDataSourceインターフェースの単純な実装であり、Beanプロパティーを介してプレーンな古いJDBC DriverManagerを構成し、すべてのgetConnection呼び出しから新しい接続を返します。注:このクラスは実際の接続プールではありません。実際には接続をプールしません。これは、本格的な接続プールの単純な代替として機能し、同じ標準インターフェイスを実装しますが、呼び出しごとに新しい接続を作成します。

だから私は今これを次のように置き換えました:

<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"/> 
    <property name="jdbcUrl" value="jdbc:mysql://server.domain/database"/> 
    <property name="user" value="theUsername"/> 
    <property name="password" value="thePassword"/> 
</bean>

c3p0-0.9.1.2.jarもその接続プールを使用するため、スローする必要がありました。

于 2010-04-07T19:34:37.357 に答える