Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot with JNDI Data Source

I have a new Spring Boot web application that I want to connect to a JNDI data source (a MySQL database defined in Tomcat's context.xml).

However when I attempt this, I always get the following exception;

org.springframework.beans.factory.BeanCreationException: Cannot determine embedded database url for database type NONE. If you want an embedded database please put a supported on on the classpath.

This is despite my pom.xml containing the MySQL connector

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>org.test</groupId>
<artifactId>twojndi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>Two JNDI Data Sources</name>
<description>Two JNDI Data Sources Example</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.1.8.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-entitymanager</artifactId>
            </exclusion>
            <exclusion>
                <artifactId>tomcat-jdbc</artifactId>
                <groupId>org.apache.tomcat</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
    </dependency>
</dependencies>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <start-class>org.test.twojndi.Application</start-class>
    <java.version>1.7</java.version>
</properties>

<build>
    <finalName>${artifactId}</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

</project>

I have defined my application.properties as follows to use the jndi-name property.

spring.datasource.jndi-name=java:comp/env/jdbc/twojndi_ds1
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

However despite that it seems Spring believes that an in-memory database should be used.

I am able to connect to the MySQL database if I define my application.properties as so

spring.datasource.url=jdbc:mysql://localhost:3306/twojndi_ds1
spring.datasource.username=twojndi
spring.datasource.password=twojndi
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect

Can anyone help me connect to JNDI with Spring Boot?

like image 544
johnmmcparland Avatar asked Oct 22 '14 10:10

johnmmcparland


People also ask

Is JNDI used in Spring?

JPA Configuration – Model, DAO and Service. With this, you have everything you need in order to use your JNDI datasource in your Spring application.

What is the use of JNDI DataSource?

A JNDI DataSource object is a file that contains the configuration details necessary to connect to a database. The DataSource object must be registered on a JNDI server, where it is identified using a JNDI name. You can register your DataSource object directly on your application server via its JNDI service.


2 Answers

As commented by M. Deinum, JDNI lookup is implemented in Spring Boot 1.2, current version is 1.2.0.M2.

If you want to do it with Spring Boot 1.1, you can define a bean like this:

@Bean
public DataSource dataSource() {
    JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
    jndiObjectFactoryBean.setJndiName("jdbc/jndidatasource");
    try {
        jndiObjectFactoryBean.afterPropertiesSet();
    } catch (NamingException e) {
        LOGGER.error("Error while retrieving datasource with JNDI name jdbc/jndidatasource", e);
    }
    return (DataSource) jndiObjectFactoryBean.getObject();
}
like image 185
dunni Avatar answered Oct 12 '22 14:10

dunni


For me it worked the following configuration, guided by the recipe exposed in this link, but as they said before the same work with versions of spring boot 1.2 or more

public class DomainAndPersistenceJndi {
private JpaVendorAdapter jpaVendorAdapter() {
    HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
    hibernateJpaVendorAdapter.setShowSql(true);
    hibernateJpaVendorAdapter.setDatabase(Database.INFORMIX);
    hibernateJpaVendorAdapter.setDatabasePlatform("org.hibernate...");
    return hibernateJpaVendorAdapter;
}

@Bean(name = "dataSourcejndi")
public DataSource dataSourcejndi() throws NamingException {
    JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
    bean.setJndiName("java:jboss/datasources/..." );
    bean.setProxyInterface(DataSource.class);
    bean.setLookupOnStartup(false);
    bean.afterPropertiesSet();
    return (DataSource) bean.getObject();
}

@Bean(name = "entityManagerFactoryJndi")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryJndi(@Qualifier("dataSourcejndi") DataSource dataSource) {

    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
    em.setDataSource( dataSource);
    em.setPackagesToScan(EntidadBase.class.getPackage().getName());
    em.setJpaVendorAdapter(jpaVendorAdapter());
    em.setPersistenceUnitName("BaseDSjdni");

    em.afterPropertiesSet();

    return em;      
}   

}

like image 21
wilbert Avatar answered Oct 12 '22 14:10

wilbert