Spring, Hibernate et une source de données JNDI

Spring, Hibernate et une source de données JNDI

1. Vue d'ensemble

Dans cet article, nous allons créer une application Spring en utilisant Hibernate / JPA avec une source de donnéesJNDI.

Si vous souhaitez redécouvrir les bases de Spring et Hibernate, consultezthis article.

2. Déclaration de la source de données

2.1. Système

Étant donné que nous utilisons une source de données JNDI, nous ne la définirons pas dans notre application, nous la définirons dans notre conteneur d'application.

Dans cet exemple, nous allons utiliser la version 8.5.x deTomcat et la version 9.5.x de la base de donnéesPostgreSQL.

Vous devriez pouvoir répliquer les mêmes étapes à l'aide de tout autre conteneur d'applications Java et d'une base de données de votre choix (à condition que vous disposiez des fichiers JDBC appropriés!).

2.2. Déclaration de la source de données sur le conteneur d'application

Nous déclarerons notre source de données dans le fichier<tomcat_home>/conf/server.xml à l'intérieur de l'élément<GlobalNamingResources>.

En supposant que le serveur de base de données s'exécute sur la même machine que le conteneur d'application, que la base de données prévue est nomméepostgres et que le nom d'utilisateur estexample avec le mot de passepass1234, une ressource ressemble à ca:

Notez que nous avons nommé notre ressourcejdbc/exampleDatabase. Ce sera le nom à utiliser pour référencer cette source de données.

Nous avons également dû spécifier son type et le nom de classe du pilote de base de données. Pour que cela fonctionne, vous devez également placer le fichier jar correspondant dans<tomcat_home>/lib/ (dans ce cas, le jar JDBC de PostgreSQL).

Les paramètres de configuration restants sont:

  • auth=”Container” - signifie que le conteneur se connectera au gestionnaire de ressources au nom de l'application

  • maxTotal, maxIdle, etmaxWaitMillis - sont les paramètres de configuration de la connexion au pool

Nous devons également définir unResourceLink à l'intérieur de l'élément<Context> dans<tomcat_home>/conf/context.xml, qui ressemblerait à:

Notez que nous utilisons le nom que nous avons défini dans nosResource enserver.xml.

3. Utilisation de la ressource

3.1. Définition de l'application

Nous allons maintenant définir une simple application Spring + JPA + Hibernate utilisant une configuration Java pure.

Nous allons commencer par définir la configuration du contexte Spring (gardez à l'esprit que nous nous concentrons ici sur JNDI et en supposant que vous connaissez déjà les bases de la configuration de Spring):

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:persistence-jndi.properties")
@ComponentScan("com.example.hibernate.cache")
@EnableJpaRepositories(basePackages = "com.example.hibernate.cache.dao")
public class PersistenceJNDIConfig {

    @Autowired
    private Environment env;

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory()
      throws NamingException {
        LocalContainerEntityManagerFactoryBean em
          = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());

        // rest of entity manager configuration
        return em;
    }

    @Bean
    public DataSource dataSource() throws NamingException {
        return (DataSource) new JndiTemplate().lookup(env.getProperty("jdbc.url"));
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(emf);
        return transactionManager;
    }

    // rest of persistence configuration
}

Notez que nous avons un exemple complet de la configuration dans l'articleSpring 4 and JPA with Hibernate.

Afin de créer notre beandataSource, nous devons rechercher la ressource JNDI que nous avons définie dans notre conteneur d'application. Nous allons stocker cela dans la clé depersistence-jndi.properties(entre autres propriétés):

jdbc.url=java:comp/env/jdbc/exampleDatabase

Notez que dans lesjdbc.url property, nous définissons un nom racine à rechercher:java:comp/env/ (ce sont les valeurs par défaut et correspondent au composant et à l'environnement), puis le même nom que nous avons utilisé dansserver.xml: jdbc/exampleDatabase.

3.2. Configuration JPA - Modèle, DAO et service

Nous allons utiliser un modèle simple avec l'annotation@Entity avec unid et unname générés:

@Entity
public class Foo {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name = "NAME")
    private String name;

    // default getters and setters
}

Définissons un référentiel simple:

@Repository
public class FooDao {

    @PersistenceContext
    private EntityManager entityManager;

    public List findAll() {
        return entityManager
          .createQuery("from " + Foo.class.getName()).getResultList();
    }
}

Et enfin, créons un service simple:

@Service
@Transactional
public class FooService {

    @Autowired
    private FooDao dao;

    public List findAll() {
        return dao.findAll();
    }
}

Avec cela, vous avez tout ce dont vous avez besoin pour utiliser votre source de données JNDI dans votre application Spring.

4. Conclusion

Dans cet article, nous avons créé un exemple d'application Spring avec une configuration JPA + Hibernate fonctionnant avec une source de données JNDI.

Notez que les éléments les plus importants sont la définition de la ressource dans le conteneur d'applications et la recherche de la ressource JNDI dans la configuration.

Et, comme toujours, le projet complet peut être trouvéover on GitHub.