I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

In this article, we’ll create a Spring application using Hibernate/JPA with a JNDI datasource.

If you want to rediscover the basics of Spring and Hibernate, check out this article.

2. Declaring the Datasource

2.1. System

Since we’re using a JNDI datasource, we won’t define it in our application, we’ll define it in our application container.

In this example, we’re going to use 8.5.x version of Tomcat and the 9.5.x version of the PostgreSQL database.

You should be able to replicate the same steps using any other Java application container and a database of your choice (as long as you have proper JDBC jars for it!).

2.2. Declaring the Datasource on the Application Container

We’ll declare our datasource in <tomcat_home>/conf/server.xml file inside the <GlobalNamingResources> element.

Assuming that the database server is running on the same machine as the application container, and that the intended database is named postgres, and that the username is baeldung with password pass1234, a resource would look like this:

<Resource name="jdbc/BaeldungDatabase" 
  auth="Container"
  type="javax.sql.DataSource" 
  driverClassName="org.postgresql.Driver"
  url="jdbc:postgresql://localhost:5432/postgres"
  username="baeldung" 
  password="pass1234" 
  maxTotal="20" 
  maxIdle="10" 
  maxWaitMillis="-1"/>

Take note that we’ve named our resource jdbc/BaeldungDatabase. This will be the name to be used when referencing this datasource.

We’ve also had to specify its type and database driver’s class name. For it to work, you must also place the corresponding jar in <tomcat_home>/lib/ (in this case, PostgreSQL’s JDBC jar).

Remaining configuration parameters are:

  • auth=”Container” – means that the container will be signing on to the resource manager on behalf of the application
  • maxTotal, maxIdle, and maxWaitMillis – are pool connection’s configuration parameters

We must also define a ResourceLink inside the <Context> element in <tomcat_home>/conf/context.xml, which would look like:

<ResourceLink 
  name="jdbc/BaeldungDatabase" 
  global="jdbc/BaeldungDatabase" 
  type="javax.sql.DataSource"/>

Note that we are using the name we defined in our Resource in server.xml.

3. Using the Resource

3.1. Setting the Application

We’re going to define a simple Spring + JPA + Hibernate application using pure Java config now.

We’ll start by defining the Spring context’s configuration (keep in mind that we are focusing on JNDI here and assuming that you already know the basics of Spring’s configuration):

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:persistence-jndi.properties")
@ComponentScan("org.baeldung.persistence")
@EnableJpaRepositories(basePackages = "org.baeldung.persistence.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
}

Note that we have a full example of the configuration in the Spring 4 and JPA with Hibernate article.

In order to create our dataSource bean, we need to look for the JNDI resource we defined at our application container. We’ll store this in persistence-jndi.properties key (among other properties):

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

Note that in the jdbc.url property we’re defining a root name to look for: java:comp/env/ (this are defaults and correspond to component and environment) and then the same name we used in server.xml: jdbc/BaeldungDatabase.

3.2. JPA Configuration – Model, DAO and Service

We’re going to use a simple model with the @Entity annotation with a generated id and a name:

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

Let’s define a simple repository:

@Repository
public class FooDao {

    @PersistenceContext
    private EntityManager entityManager;

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

And lastly, let’s create a simple service:

@Service
@Transactional
public class FooService {

    @Autowired
    private FooDao dao;

    public List<Foo> findAll() {
        return dao.findAll();
    }
}

With this, you have everything you need in order to use your JNDI datasource in your Spring application.

4. Conclusion

In this article, we’ve created an example Spring application with a JPA + Hibernate setup working with a JNDI datasource.

Note that the most important parts are the definition of the resource in the application container and the lookup for the JNDI resource on the configuration.

And, as always, the full project can be found over on GitHub.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS