Spring, Hibernate und eine JNDI-Datenquelle

Spring, Hibernate und eine JNDI-Datenquelle

1. Überblick

In diesem Artikel erstellen wir eine Spring-Anwendung mit Hibernate / JPA mit einerJNDI-Datenquelle.

Wenn Sie die Grundlagen von Spring und Hibernate neu entdecken möchten, lesen Siethis article.

2. Deklarieren der Datenquelle

2.1. System

Da wir eine JNDI-Datenquelle verwenden, definieren wir sie nicht in unserer Anwendung, sondern in unserem Anwendungscontainer.

In diesem Beispiel verwenden wir die 8.5.x-Version vonTomcat und die 9.5.x-Version derPostgreSQL-Datenbank.

Sie sollten in der Lage sein, dieselben Schritte mit jedem anderen Java-Anwendungscontainer und einer Datenbank Ihrer Wahl zu replizieren (vorausgesetzt, Sie haben die richtigen JDBC-Jars dafür!).

2.2. Deklarieren der Datenquelle im Anwendungscontainer

Wir deklarieren unsere Datenquelle in der Datei<tomcat_home>/conf/server.xmlinnerhalb des Elements<GlobalNamingResources>.

Angenommen, der Datenbankserver wird auf demselben Computer wie der Anwendungscontainer ausgeführt und die beabsichtigte Datenbank heißtpostgres, und der Benutzername lautetexample mit dem Kennwortpass1234, würde eine Ressource sieht aus wie das:

Beachten Sie, dass wir unsere Ressourcejdbc/exampleDatabase benannt haben. Dies ist der Name, der beim Verweisen auf diese Datenquelle verwendet wird.

Wir mussten auch den Typ und den Klassennamen des Datenbanktreibers angeben. Damit dies funktioniert, müssen Sie auch das entsprechende JAR in<tomcat_home>/lib/ platzieren (in diesem Fall das JDBC-JAR von PostgreSQL).

Die verbleibenden Konfigurationsparameter sind:

  • auth=”Container” - bedeutet, dass sich der Container im Namen der Anwendung beim Ressourcenmanager anmeldet

  • maxTotal, maxIdle, undmaxWaitMillis - sind die Konfigurationsparameter der Poolverbindung

Wir müssen auch einResourceLink innerhalb des<Context>-Elements in<tomcat_home>/conf/context.xml, definieren, das wie folgt aussehen würde:

Beachten Sie, dass wir den Namen verwenden, den wir inResource inserver.xml definiert haben.

3. Verwenden der Ressource

3.1. Einstellen der Anwendung

Wir werden jetzt eine einfache Spring + JPA + Hibernate-Anwendung mit reiner Java-Konfiguration definieren.

Zunächst definieren wir die Konfiguration des Spring-Kontexts (denken Sie daran, dass wir uns hier auf JNDI konzentrieren und davon ausgehen, dass Sie die Grundlagen der Spring-Konfiguration bereits kennen):

@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
}

Beachten Sie, dass wir ein vollständiges Beispiel für die Konfiguration im Artikel vonSpring 4 and JPA with Hibernatehaben.

Um unseredataSource-Bean zu erstellen, müssen wir nach der JNDI-Ressource suchen, die wir in unserem Anwendungscontainer definiert haben. Wir speichern dies inpersistence-jndi.properties Schlüssel (unter anderen Eigenschaften):

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

Beachten Sie, dass wir injdbc.url property einen Stammnamen definieren, nach dem gesucht werden soll:java:comp/env/ (dies sind Standardeinstellungen und entsprechen der Komponente und Umgebung) und dann denselben Namen, den wir inserver.xml verwendet haben: jdbc/exampleDatabase.

3.2. JPA-Konfiguration - Modell, DAO und Service

Wir werden ein einfaches Modell mit der Annotation@Entity mit einem generiertenid und einemname verwenden:

@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
}

Definieren wir ein einfaches Repository:

@Repository
public class FooDao {

    @PersistenceContext
    private EntityManager entityManager;

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

Und zum Schluss erstellen wir einen einfachen Service:

@Service
@Transactional
public class FooService {

    @Autowired
    private FooDao dao;

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

Damit haben Sie alles, was Sie brauchen, um Ihre JNDI-Datenquelle in Ihrer Spring-Anwendung zu verwenden.

4. Fazit

In diesem Artikel haben wir eine Spring-Beispielanwendung mit einem JPA + Hibernate-Setup erstellt, das mit einer JNDI-Datenquelle arbeitet.

Beachten Sie, dass die wichtigsten Teile die Definition der Ressource im Anwendungscontainer und die Suche nach der JNDI-Ressource in der Konfiguration sind.

Und wie immer kann das vollständige Projekt inover on GitHub gefunden werden.