Spring Boot with JNDI Data Source

2019-04-06 18:36发布

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?

2条回答
▲ chillily
2楼-- · 2019-04-06 19:24

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();
}
查看更多
该账号已被封号
3楼-- · 2019-04-06 19:32

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

}

查看更多
登录 后发表回答