java - 关闭 Spring 应用程序会使数据源的 JNDI 名称脱离 jdbc 上下文

标签 java spring servlets weblogic jndi

我正在尝试在我的 Weblogic 上使用 Spring MVC 和 Spring Data JPA 设置 Web 应用程序 服务器。该应用程序在我第一次部署到 Weblogic 服务器时运行良好,但是当我停止应用程序时,我的数据源的 jndi 名称 (jdbc/myDS) 从我的 Weblogic 服务器上的 JNDI 树中消失了,然后当我尝试启动应用程序时我再次收到以下错误:

Caused By: javax.naming.NameNotFoundException: Unable to resolve 'jdbc.myDS'. Resolved 'jdbc'; remaining name 'myDS'

我在启动时在 JPAConfiguratation.java 中设置以下内容:

package mySpringApp.application;

import java.util.Properties;

import javax.annotation.Resource;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * An application context Java configuration class. The usage of Java configuration
 * requires Spring Framework 3.0 or higher with following exceptions:
 * <ul>
 *     <li>@EnableWebMvc annotation requires Spring Framework 3.1</li>
 * </ul>
 */
@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
@ImportResource("classpath:applicationContext.xml")
@PropertySource("classpath:application.properties")
public class JPAConfiguration{

    private static final Logger logger = LoggerFactory.getLogger(JPAConfiguration.class);

    private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
    private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";
    private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";
    private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
    private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";

    @Resource
    private Environment environment;

    @Bean
    public DataSource dataSource() throws NamingException {    
        Context ctx = new InitialContext();
        String jndiName = "jdbc/myDS";
        DataSource dataSourceJNDINAME = (DataSource) ctx.lookup(jndiName);
        return dataSourceJNDINAME;
    ));


    @Bean
    public JpaTransactionManager transactionManager() throws ClassNotFoundException {
        JpaTransactionManager transactionManager = new JpaTransactionManager();

        transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());

        return transactionManager;
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() throws ClassNotFoundException {
        LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();

        try {
            entityManagerFactoryBean.setDataSource(dataSource());
        } catch (Exception e) {
            // TODO Auto-generated catch block
            logger.error("Error setting datasource for entityManagerFactoryBean", e);
            logger.error(e.getMessage());
        }
        entityManagerFactoryBean.setPackagesToScan(environment.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));

        JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        entityManagerFactoryBean.setJpaVendorAdapter(vendorAdapter);

        Properties jpaProterties = new Properties();
        jpaProterties.put(PROPERTY_NAME_HIBERNATE_DIALECT, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
        jpaProterties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
        jpaProterties.put(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY));
        jpaProterties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));

        entityManagerFactoryBean.setJpaProperties(jpaProterties);

        return entityManagerFactoryBean;
    }

Web.xml:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">

    <servlet>
        <servlet-name>MySpringApp</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>mySpringApp.application</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>MySpringApp</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

第一次关闭应用时的日志输出:

INFO  - onfigWebApplicationContext - Closing WebApplicationContext for namespace 'MySpringApp-servlet': startup date [Thu Oct 03 13:13:05 CEST 2013]; root of context hierarchy
DEBUG - DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor'
INFO  - DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1c51f5cb: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcesso
r,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.sprin
gframework.context.annotation.internalPersistenceAnnotationProcessor,webConfig,JPAConfiguration,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,homeController,firstController,buildController,
greetingController,repositoryBuildService,org.springframework.data.repository.core.support.RepositoryInterfaceAwareBeanPostProcessor#0,org.springframework.aop.config.internalAutoProxyCreator,org.springframework.data.repository.core.sup
port.RepositoryInterfaceAwareBeanPostProcessor#1,org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration,requestMappingHandlerMapping,mvcContentNegotiationManager,viewControllerHandlerMapping,beanNameHandlerMapp
ing,resourceHandlerMapping,defaultServletHandlerMapping,requestMappingHandlerAdapter,mvcConversionService,mvcValidator,httpRequestHandlerAdapter,simpleControllerHandlerAdapter,handlerExceptionResolver,messageSource,viewResolver,org.spr
ingframework.web.servlet.resource.ResourceHttpRequestHandler#0,org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.Http
RequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#0,org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#1,buil
dRepository,org.springframework.data.repository.core.support.RepositoryInterfaceAwareBeanPostProcessor#2,org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration,org.springframework.transaction.config.internal
TransactionAdvisor,transactionAttributeSource,transactionInterceptor,dataSource,transactionManager,entityManagerFactoryBean,org.springframework.web.servlet.resource.ResourceHttpRequestHandler#1,org.springframework.web.servlet.handler.S
impleUrlHandlerMapping#2,org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler#1,org.springframework.web.servlet.handler.SimpleUrlHandlerMapping#3,org.springframework.data.repository.core.support.RepositoryInterface
AwareBeanPostProcessor#3]; root of factory hierarchy
DEBUG - DisposableBeanAdapter      - Invoking destroy() on bean with name 'org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration'
DEBUG - DefaultListableBeanFactory - Retrieved dependent beans for bean '(inner bean)': [(inner bean), buildRepository]
DEBUG - DisposableBeanAdapter      - Invoking destroy() on bean with name 'entityManagerFactoryBean'
INFO  - erEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'mySpringAppPersistenceUnit'
DEBUG - SessionFactoryImpl         - HHH000031: Closing
DEBUG - tityManagerFactoryRegistry - Remove: name=mySpringAppPersistenceUnit
DEBUG - DisposableBeanAdapter      - Invoking destroy method 'shutdown' on bean with name 'dataSource'
DEBUG - DisposableBeanAdapter      - Invoking destroy() on bean with name 'JPAConfiguration'
DEBUG - DisposableBeanAdapter      - Invoking destroy() on bean with name 'webConfig'
DEBUG - DisposableBeanAdapter      - Invoking destroy() on bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration'

我正在使用:

  • Spring 3.2.4.RELEASE
  • hibernate 4.2.6.Final
  • Weblogic 10.3.5

我是否需要以某种方式手动关闭应用程序?什么会导致 jndi 名称从服务器上下文中消失?

非常感谢所有帮助!

最佳答案

我遇到了同样的问题。添加 destroyMethod=""为我修复了它。

显然,如果没有destroyMethod,Spring 会尝试确定destroy 方法是什么。这显然会导致关闭数据源并从树中删除 JNDI 键。将其更改为 ""会强制它不寻找 destroyMethod。

@Bean(destroyMethod = "")
public DataSource dataSource() throws NamingException{
    Context context = new InitialContext();
    return (DataSource)context.lookup("jdbc.mydatasource");
}

关于java - 关闭 Spring 应用程序会使数据源的 JNDI 名称脱离 jdbc 上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19158334/

相关文章:

java - 相当于 Spring 框架的资源抽象

java - 将类级别 @PreAuthorized 注释与方法级别 @PreAuthorzied 注释一起使用

java - 如何迭代并从 session 中获取所有用户名

java - "References to generic type JsonResponse should be parameterized"

java - 如何执行包含来自不同java程序(runtime.exec())的带有某些参数的方法的java类文件?

java - 使用 Maven for openshift 构建时出错

java - 如何从现场注入(inject)?

c# - 如何更改剑道错误信息?

java - 使用单例成员/值参数配置原型(prototype) bean

java - 修复动态 Web 项目中的 JDBC