简体   繁体   中英

Using JNDI is significantly slower than explicit connection in persistence.xml (Jetty 9/Hibernate)

On a standalone Jetty 9.4 server I am deploying an app which utilizes hibernate JPA. I have observed the following strange behaviour (might not be strange, I am sure I am just missing some concept)

If I explicitly declare db connection properties in the applications persistence xml, I get 15-20 ms responses for a service that reads some dummy data from the db. It is like 300ms for the first try, then the pooling kicks in.

If I use a JNDI datasource and reference it in the persistence xml, I get 1 second initial response time, then it is between 300-400 ms on the same local environment.

My question would be that is that a normal behaviour? Is JNDI always that slow or it may just be some bad configuration? Is it the jetty implementation that is slow?

ps I have tried to declare a PoolDataSource as the JNDI resource, but persistence.xml does not accept it.

Thanks in advance for the answers.

persistence.xml

    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
    <persistence-unit name="flapweb">
        <non-jta-data-source>java:comp/env/jdbc/mydatasource</non-jta-data-source>
        <properties>
            <!--property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://localhost:5433/postgres" />
            <property name="javax.persistence.jdbc.user" value="user" />
            <property name="javax.persistence.jdbc.password" value="password" /-->

            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> <!-- DB Dialect -->
            <property name="hibernate.hbm2ddl.auto" value="update" /> <!-- create / create-drop / update -->

            <property name="hibernate.show_sql" value="true" /> <!-- Show SQL in console -->
            <property name="hibernate.format_sql" value="true" /> <!-- Show SQL formatted -->

            <property name="hibernate.c3p0.min_size" value="5" />
            <property name="hibernate.c3p0.max_size" value="20" />
            <property name="hibernate.c3p0.timeout" value="500" />
            <property name="hibernate.c3p0.max_statements" value="50" />
            <property name="hibernate.c3p0.idle_test_period" value="2000" />
        </properties>
    </persistence-unit>
</persistence>

Datasource JNDI declaration

    <?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">


<Configure id="Server" class="org.eclipse.jetty.server.Server">

    <New id="mydatasource" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg></Arg>
        <Arg>jdbc/mydatasource</Arg>
        <Arg>
            <New class="org.postgresql.ds.PGSimpleDataSource">
                <Set name="databaseName">postgres</Set>
                <Set name="serverName">localhost</Set>
                <Set name="portNumber">5433</Set>
                <Set name="user">user</Set>
                <Set name="password">password</Set>
            </New>
        </Arg>
    </New>

</Configure>

Okay, after many attempts I have found the solution.

Short anwser, I have to use a c3po DataSource as a JNDI resource, so the retrieved connection will always come from a pool. I also do not need any hibernate.c3p0.* settings. Example: https://www.eclipse.org/jetty/documentation/9.4.x/jndi-datasource-examples.html#c3p0-datasource . c3po and postgres jars need to be at jetty classpath.

The reason why my previous solution did not work is because it seems that hibernate does not apply any c3po/connection pool settings to JNDI retrieved datasources, because it assumes that it is managed by the application server / servlet container.

I also could not use PGConnectionPoolDataSource because that class does not implement the javax.sql.DataSource hence it cannot be referenced in persistence xml.

I hope this will help someone in the future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM