SpringBoot部署到Weblogic后的DB问题

总结一下遇到的问题,为遇到同样问题的同学提供些帮助。

SpringBoot部署到Weblogic后,发现DB的事务处理有问题。Debug程序发现程序的事务已经提交了,但要执行的SQL文没有被执行到。

原来的SpringBoot的DB连接配置是Spring datasource到Oracle DB,事务也是Spring的。

部署到Weblogic后发现DB的数据怎么都更新不了。

一通乱查,发现Weblogic的JTA管理是如下图

看这个图就能发现,程序只是把事务提交到了Weblogic的TM了。查了一下好像也不能关闭这个Weblogic的事务管理。

那也就只能把DB的配置在Weblogic来做,配置JNDI,修改SpringBoot的DB连接方式如下。

配置文件

spring:
  datasource:
     jndi-name: jdbc/abcd

weblogic:
  url: 't3://localhost:7001'
  jndiName: jdbc/abcd
  webLogicName: weblogic
  password:  weblogic123

新建DataSource类

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jndi.JndiObjectFactoryBean;

import javax.naming.Context;
import javax.naming.NamingException;
import javax.sql.DataSource;
import java.util.Properties;

@Configuration
public class DataSourceConfig {

    @Value("${weblogic.url}")
    private String webLogicUrl;

    @Value("${weblogic.jndiName}")
    private String weblogicJndiName;

    @Value("${weblogic.webLogicName}")
    private String weblogicLogicName;

    @Value("${weblogic.password}")
    private String weblogicPassword;

    @Bean(name = "dataSource")
    public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {
        JndiObjectFactoryBean bean = new JndiObjectFactoryBean();
        Properties properties = new Properties();
        properties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
        properties.put(Context.PROVIDER_URL, webLogicUrl);
        properties.put(Context.SECURITY_PRINCIPAL, weblogicLogicName);
        properties.put(Context.SECURITY_CREDENTIALS, weblogicPassword);
        bean.setJndiEnvironment(properties);
        bean.setResourceRef(true);
        bean.setJndiName(weblogicJndiName);
        bean.setProxyInterface(DataSource.class);
        bean.setLookupOnStartup(false);
        bean.afterPropertiesSet();
        return (DataSource) bean.getObject();
    }
}

现在开始才是坑

启动项目,有Error,springboot .ClassNotFoundException: weblogic.jndi.WLInitialContextFactory

查网络,说要加wlclient.jar和weblogic.jar,去Weblogic的Bin目录下把Jar文件拷出来,加完后,又有下面的错

spring oracle.jdbc.driver.T4CConnection cannot be cast to java.io.Serializable

再查网络说要wlfullclient.jar,这个Jar,weblogic没有啊,再查,原来是要自己做,参考下面的网址

https://docs.oracle.com/cd/E12839_01/web.1111/e13717/jarbuilder.htm#SACLT239

把wlfullclient.jar做好加项目里面(可以把以上的wlclient.jar和weblogic.jar在项目去除)

又有新错,

java.lang.NoSuchMethodError: javax.validation.BootstrapConfiguration.getClockProviderClassName()Ljava/lang/String

参考万能的StackOverflow,降级hibernate-validator

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.4.2.Final</version>
    </dependency>

再起动项目,终于没有错了,打开页面,Debug一下更新DB,一切正常了。