37

I've seen (and done) data source configuration in two ways (the code below is just for demo):

1) configuration inside persistence units, like:

<persistence-unit name="LocalDB" transaction-type="RESOURCE_LOCAL">
    <class>domain.User</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
        <property name="hibernate.connection.url" value="jdbc:hsqldb:hsql://localhost"/>
        <property name="hibernate.hbm2ddl.auto" value="create"/>
        <property name="hibernate.c3p0.min_size" value="5"/>
        ....
        <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
    </properties>
</persistence-unit>

2) configuration inside spring configuration files (like applicationContext.xml):

<bean id="domainEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="JiraManager"/>
    <property name="dataSource" ref="domainDataSource"/>
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
            <property name="generateDdl" value="false"/>
            <property name="showSql" value="false"/>
            <property name="databasePlatform" value="${hibernate.dialect}"/>
        </bean>
    </property>
</bean>

<bean id="domainDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${db.driver}" />
    <property name="jdbcUrl" value="${datasource.url}" />
    <property name="user" value="${datasource.username}" />
    <property name="password" value="${datasource.password}" />
    <property name="initialPoolSize" value="5"/>
    <property name="minPoolSize" value="5"/>
    .....
</bean>

The question is: are there any pros and cons of each way, or it's just a matter of taste?

Roman
  • 64,384
  • 92
  • 238
  • 332
  • After thinking once more about your question: isn't your *actual* question more "What's the advantage of Spring?", it sounds like as if you don't see it. Ask yourself: Why are you using it? – BalusC Jun 24 '10 at 17:32
  • @BalusC: I don't know the ways these configurations are transformed into `entityManagerFactory` at startup. If the same things are going then the answer to my question whould be `it's a matter of taste`. If something different is going then I want to know the difference. – Roman Jun 24 '10 at 17:46
  • I wouldn't call using Spring "a matter of taste". You use it with a reason: IoC. I actually posted an answer which reads like *"Well, if you're using Spring and/or want IoC (that's Spring's job), then go for Spring, else just "plain" JPA."* but I deleted it after a second thought about your question since the actual problem seems to be deeper than that. – BalusC Jun 24 '10 at 17:53
  • @BalusC: ok, I see that the answer, if it exists, is not on the surface. But can you tell me, where do you place datasource configuration in your projects with Spring and JPA (if you do any with both technologies)? – Roman Jun 24 '10 at 18:03
  • I don't use Spring :) If I were using it, I would have let Spring manage it. You could then take advantage of its IoC capabilities. But still, I wonder if you didn't already thought about that, I just wouldn't play for Mr.Obvious. *Btw: deleted answers are visible for 10K+ and undeletable anyway.* – BalusC Jun 24 '10 at 18:11
  • @BalusC: then I'll see your answer in a month or two :) – Roman Jun 24 '10 at 18:16
  • It's nothing special. I've already copied it fully and literally in the 2nd comment. – BalusC Jun 24 '10 at 18:27

2 Answers2

32

It makes a huge difference if you're in a JavaEE container.

More than personal preference, you're much better off if you follow the second approach with a few modifications.

In the first case, you're creating your own connection pool and do not profit from the existing connection pool in the container. Thus even if you configured your container to, say, a max of 20 simultaneous connections to the database, you can't guarantee this max as this new connection pool is not restrained by your configuration. Also, you don't profit from any monitoring tools your container provides you.

In the second case, you're also creating your own connection pool, with the same disadvantages as above. However, you can isolate the definition of this spring bean and only use it in test runs.

Your best bet is to look up the container's connection pool via JNDI. Then you are sure to respect the data source configurations from the container.

Use this for running tests.

<!-- datasource-test.xml -->
<bean id="domainDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
   <property name="driverClass" value="${db.driver}" />
   <property name="jdbcUrl" value="${datasource.url}" />
   <property name="user" value="${datasource.username}" />
   <property name="password" value="${datasource.password}" />
   <property name="initialPoolSize" value="5"/>
   <property name="minPoolSize" value="5"/>
.....
</bean>

Use this when deploying to a JavaEE container

<!-- datasource.xml -->
<jee:jndi-lookup id="domainDataSource" jndi-lookup="jndi/MyDataSource" />
  • Remember to set the JEE schema
  • Although Tomcat is not a full JavaEE container, it does manage data sources via JNDI, so this answer still applies.
Leonel
  • 28,541
  • 26
  • 76
  • 103
  • Thanks! Nice point! I used only Tomcat for a long time, but my current project is deployed in Glassfish and your suggestions expain me why some things are made in the way they are made. – Roman Nov 09 '10 at 20:41
4

It is strictly personal preference.

My suggestion would be to use Spring's configuration if you are using Spring already. Its purpose is dependency injection and management so let it do its job with respect to your dependency on a database. If, however, you are not already using Spring, stick with the persistence configuration considering that this will keep your project simpler while still functional. I will suggest though that any project that needs Hibernate to interact with a database is probably big enough to condone using Spring within.

Jesse Webb
  • 43,135
  • 27
  • 106
  • 143