Spring, Hibernate and a JNDI Datasource – Spring、Hibernate和一个JNDI数据源

最后修改: 2016年 9月 26日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

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

在本文中,我们将使用Hibernate/JPA创建一个带有JNDI>数据源的Spring应用程序。

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

如果你想重新发现Spring和Hibernate的基础知识,请查看这篇文章

2. Declaring the Datasource

2.声明数据源

2.1. System

2.1.系统

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

由于我们使用的是JNDI数据源,我们不会在我们的应用程序中定义它,我们将在我们的应用程序容器中定义它。

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

在这个例子中,我们将使用8.5.x版本的Tomcat和9.5.x版本的PostgreSQL数据库。

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!).

你应该能够使用任何其他的Java应用容器和你选择的数据库来复制同样的步骤(只要你有合适的JDBC罐子就可以了!)。

2.2. Declaring the Datasource on the Application Container

2.2.在应用容器上声明数据源

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

我们将在<tomcat_home>/conf/server.xml文件中的<GlobalNamingResources>元素内声明我们的数据源。

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:

假设数据库服务器与应用程序容器运行在同一台机器上,并且预期的数据库被命名为postgres,并且用户名是baeldung,密码是pass1234,那么资源将看起来像这样。

<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.

请注意,我们已经将我们的资源命名为jdbc/BaeldungDatabase。这将是引用该数据源时要使用的名称。

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).

我们还必须指定其类型和数据库驱动程序的类名。为了让它工作,你还必须把相应的jar放在<tomcat_home>/lib/中(本例中是PostgreSQL的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:

我们还必须在<Context>中的<tomcat_home>/conf/context.xml中定义一个ResourceLink,它看起来像。

<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.

注意,我们使用的是我们在server.xmlResource定义的名称。

3. Using the Resource

3.使用资源

3.1. Setting the Application

3.1.设置应用程序

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

我们现在要用纯Java配置来定义一个简单的Spring + JPA + Hibernate应用。

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):

我们将从定义Spring上下文的配置开始(请记住,我们在这里关注的是JNDI,并假设你已经知道Spring配置的基础知识)。

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

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

请注意,我们在Spring 4 and JPA with Hibernate文章中提供了完整的配置示例。

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):

为了创建我们的dataSourcebean,我们需要寻找我们在应用容器中定义的JNDI资源。我们将把它存储在persistence-jndi.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.

注意,在jdbc.url属性中,我们定义了一个要寻找的根名称。java:comp/env/(这是默认值,对应于组件和环境),然后是我们在server.xml中使用的相同名称。jdbc/BaeldungDatabase

3.2. JPA Configuration – Model, DAO and Service

3.2.JPA配置–模型、DAO和服务

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

我们将使用一个带有@Entity注解的简单模型,它有一个生成的id和一个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.

有了这些,你就拥有了在Spring应用程序中使用JNDI数据源所需的一切。

4. Conclusion

4.结论

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

在这篇文章中,我们创建了一个Spring应用程序的例子,它采用JPA+Hibernate设置,与JNDI数据源一起工作。

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.

注意,最重要的部分是应用容器中资源的定义和配置上JNDI资源的查找。

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

而且,像往常一样,完整的项目可以在GitHub上找到