Configure Spring applicationContext by taking advantage of other configuration files

Asked

Viewed 1,481 times

1

I got the following hibernate.cfg.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <!-- Configuração para a instância do SessionFactory -->
    <session-factory>

        <!-- Propriedades para o Hibernate -->
        <property name="hibernate.dialect">
            org.hibernate.dialect.MySQL5InnoDBDialect
        </property>
        <property name="hibernate.show_sql">
            true
        </property>
        <property name="hibernate.connection.provider_class">
            com.zaxxer.hikari.hibernate.HikariConnectionProvider
        </property>
        <property name="hibernate.current_session_context_class">
            thread
        </property>
        <property name="hibernate.generator_mappings">
            true
        </property>

        <!-- Propriedades para o Pool de Conexões HirakiCP -->
        <property name="hibernate.hikari.dataSourceClassName">
            com.mysql.jdbc.jdbc2.optional.MysqlDataSource
        </property>
        <property name="hibernate.hikari.dataSource.url">
            jdbc:mysql://localhost:3306/teste-database1?createDatabaseIfNotExist=true
        </property>
        <property name="hibernate.hikari.dataSource.user">
            root
        </property>
        <property name="hibernate.hikari.dataSource.password">
            admin123
        </property>
        <property name="hibernate.hikari.maximumPoolSize">
            10
        </property>
        <property name="hibernate.hikari.idleTimeout">
            30000
        </property>
        <property name="hibernate.hikari.dataSource.cachePrepStmts">
            true
        </property>
        <property name="hibernate.hikari.dataSource.prepStmtCacheSize">
            250
        </property>
        <property name="hibernate.hikari.dataSource.prepStmtCacheSqlLimit">
            2048
        </property>
        <property name="hibernate.hikari.dataSource.useServerPrepStmts">
            true
        </property>
        <property name="hibernate.hikari.dataSource.useLocalSessionState">
            true
        </property>
        <property name="hibernate.hikari.dataSource.useLocalTransactionState">
            true
        </property>
        <property name="hibernate.hikari.dataSource.maintainTimeStats">
            false
        </property>
        <property name="hibernate.hikari.dataSource.useUnbufferedInput">
            false
        </property>

        <!-- Mapeamento de classes -->
        <!-- <mapping package="org.sgct.model" /> -->
        <mapping class="org.teste.model.Usuario" />
        <mapping class="org.teste.model.Contato" />
        <mapping class="org.teste.model.Endereco" />

    </session-factory>

</hibernate-configuration>

Doubts

1 - In the Spring configuration file (applicationContext.xml for example) instead of having to enter each property in this file, you can take advantage of file settings hibernate.cfg.xmlusing the following code excerpt:

<bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="configLocation" value="classpath*:hibernate.cfg.xml" />
</bean>

But I don’t know what properties he takes advantage of hibernate.cfg.xml when using this code snippet. What I want to understand is which properties it takes advantage of (like maybe class mapping snippets) in addition to the basic properties (dialect, providade_class, etc.) so that I can complement the snippet with properties it doesn’t use.

2 - When configured the connection pool (in my case I am using Hikaricp) there is a similar way to take advantage of the configuration of another file as in the configuration snippet of Hibernate that I presented in the previous question?

3 - I intend to use JNDI in an xml file (in the case of Tomcat it was the file context.xml) because in addition to Hibernate I will use Spring Security, but how I use Glassfish I don’t know if this configuration that is in the Hirakicp project repository will work the same way in Glassfish because it is for Tomcat. I also don’t know if all or part of the connection pool configuration will go to the JNDI configuration file.

4 - There is also the case of referencing the connection in the configuration section of Hibernate as in my version of hibernate.cfg.xml that I put up I use the property hibernate.connection.provider_class but in this article the property is used dataSource. What is the difference between the use of one or the other? When using JNDI is used which of these?

  • A recommendation, even knowing that the questions are related, as far as possible try to break your doubts into multiple questions (this not only helps the site catalog, but increases your chances as it may be that a user is able to answer one but not all questions).

  • I get it. Thank you Anthony.

  • No problem, I wrote the answer while you were editing, I didn’t realize you had subdivided. If you want to do rollback no problem, the advice was more to help you get answers (if you want to leave subdivided I "refatoro" here too).

  • 1

    No need more, but thanks. I was subdividing the questions, but as you put an answer I came back the way it was to not complicate. But the next few questions I know how to do.

1 answer

2


TL;DR:

  • Use what you can / want from your application server
  • The more components of the Application Server you use, the simpler your configuration will be.
  • You do not need to repeat settings.
  • Virtually everything that is configurable from hibernate.cfg.xml can be configured in Spring; keep the configuration in the place that makes the most sense and where it can be better reused (e.g., a data source configured in Spring can be used with a JdbcTemplate).

Follow a summary of your doubts:

  1. As the Javadoc of the class it is not clear what features are used, see that there are extra properties to load mapping files (setMappingDirectoryLocations, setMappingJarLocations, setMappingLocations, setMappingResources). Spring will repurpose the data source, transactions, etc, but you don’t need to configure any of this in hibernate.cfg.xml (if you want, you can configure everything by Spring vide 3).
  2. Yes. Look at three:
  3. In Glassfish you will set up a pool of connections in the console itself (which will be persisted in the file domain.xml, but that’s beside the point). Use the pool from Glassfish itself, don’t worry about integrating a pool external. Additionally you wouldn’t need to set up and use Hibernate if you don’t want to. Glassfish already comes with Eclipselink, just create a file persistence.xml that it will already make the libraries available to you (this is the main advantage of a App Server vs a container like Tomcat). Of course you are free to set up and use Hibernate and take advantage of its API if you like. In Spring there is little to be done since the container will take care of the pool and transactions:

    <!-- Obtém data source do GlassFish -->
    <jee:jndi-lookup id="datasSource" 
         jndi-name="jdbc/dataSourceName" expected-type="javax.sql.DataSource" />
    <!-- Detecta e configura o provedor de transações do GlassFish -->
    <tx:jta-transaction-manager/>
    

    And then your settings LocalSessionFactoryBean or - if you prefer the pure JPA path - use the LocalContainerEntityManagerFactoryBean (see that article for more details). Both consume the dataSource and the transactionManager.

    • In the case of Hibernate, you can either skip the configuration of data source so he can use the hibernate.cfg.xml how to exclude this configuration from hibernate.cfg.xml and configure everything by Spring; you can also choose between settings with or without JTA (since Glassfish provides the service, it costs nothing). For more details see the methods setDataSource and setJtaTransactionManager

    • Similarly to JPA you can also skip the setting of data source for Spring to use what was specified in persistence.xml, or adopt the opposite strategy and exclude the relevant configuration from persistence.xml, configuring only by Spring (for more details see the methods setDataSource and setJtaDataSource.

  4. This is just a Hibernate property, if you use the data source of Connection pool You don’t have to worry about that. Imagine that you want to use a pool external and do not want to configure this property directly on hibernate.cfg.xmlit is also possible to configure it by Spring:

    • Annotation/ java settings (see example of the mentioned article):

      Properties hibernateProperties() {
          return new Properties() {
              {
                  // Demais propriedades
                  setProperty("hibernate.connection.provider_class", env.getProperty("com.zaxxer.hikari.hibernate.HikariConnectionProvider"));
              }
          };
      } 
      
    • Xml configuration:

      <bean id="sessionFactory"
          class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
          <property name="configLocation" value="classpath*:hibernate.cfg.xml" />
              <property name="hibernateProperties">
              <props>
                  <property name="hibernate.connection.provider_class" 
                      value="com.zaxxer.hikari.hibernate.HikariConnectionProvider" />
              </props>
      </bean>
      
  • Thank you for answering me Anthony. When designing an application using only Mysql for example, is it still interesting to use JTA? Because from what I read about JTA, JTA is only interesting when using multiple external resources (and not just one, in the case of Mysql), what do you think?

  • 1

    Hello Klayton, you don’t really need distributed transactions if you only have one bank; but you need one TransactionManager for Spring declarative transactions (see your previous question). While you can use one Hibernatetransactionmanager (model Session per thread),if you already have one container providing the JTA service, why not use?

  • 1

    Note that, after set, you will program the same way you would with a TransactionManager simpler, the difference is that it may include a second data source, jms queue, etc without problems, and will be using the components of the App Server.

  • I was looking at the documentation of Mysql and Glassfish and I made a connection pool, until it is not difficult, and from what I understand the control of transactions is implicitly active when creating a connection pool in Glassfish (application servers is practically new to me since I only used Tomcat). My question is that only using the tag <tx:jta-transaction-manager/> (with clear configured datasource) it is sufficient for Glassfish transaction control to be used, like, no need to create a bean of a HibernateTransactionManager (in case of use of hibernate)?

  • 1

    Opa, the idea is to be simple ;). The tx:jta-transaction-manager will detect the container and set up a bean JtaTransactionManager (by name transactionManager). It’s been a long time since I used pure Hibernate, but I think if you set up the LocalSessionFactoryBean to use this bean (using the property jtaTransactionManager) everything should work as expected. If you prefer to do everything on the Hibernate side you will need to configure the jta-data-source, as well as the properties hibernate.transaction.jta.platform and hibernate.transaction.factory_class

  • Got it. Spring makes it easy to set up. What about the properties you mentioned, jta-data-source is not a Hibernate property (I think you meant to configure the properties about Hibernate transactions), the property hibernate.transaction.jta.platform so I read in the documentation the default setting of it should suffice, the value of the hibernate.transaction.factory_class would be the org.hibernate.transaction.JTATransactionFactory for when using right JTA?

  • 1

    Opa, sorry, I shortened my comment about JTA and I ended up letting it escape (the jta-data-source is from JPA). The property I meant is hibernate.connection.datasource. About the factory_class I believe it must be org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory (to leave the container control transactions, see that improvement), and the jta.platform of the Glassfish, for historical reasons, is the org.hibernate.service.jta.platform.internal.SunOneJtaPlatform. Spring already sets all this up for you.

  • Ata, I understand, no problems. About this improvement of the CMTTransactionFactory is interesting, Hibernate had this functionality but did not work properly, the improvement ensures that one flush() of insertions and updates before any pending query.

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.