使用了错误的JDBC驱动程序

使用了错误的JDBC驱动程序

本文介绍了使用了错误的JDBC驱动程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法将记录插入Postgres DB并返回为所述记录生成的标识字段。问题是,如果我在我的POM文件中包含Redshift驱动程序,那么该驱动程序将被使用而不是Postgres驱动程序 - 并且Redshift驱动程序不允许返回标识值。

I have a method that inserts a record into a Postgres DB and returns the identity field generated for said record. The problem is, if I include the Redshift driver in my POM file, that driver is getting used instead of the Postgres driver - and the Redshift driver doesn't allow returning the identity value.

代码为:

try {
  Class.forName( "org.postgresql.Driver" ).newInstance();
  Connection connection = DriverManager.getConnection( "jdbc:postgresql://localhost:5433/postgres", "postgres", "password" );
  Statement stmt = connection.createStatement();
  stmt.execute( "insert into public.job ( job_name ) values ( 'test' )" , Statement.RETURN_GENERATED_KEYS );
  ResultSet keyset = stmt.getGeneratedKeys();
  if ( keyset.next() ) System.out.println( keyset.getLong( 1 ) );
}
catch ( Exception e ) {
  e.printStackTrace();
}

使用此POM时,它可以正常工作:

When this POM is used, it works:

<dependencies>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.4-1201-jdbc41</version>
    </dependency>
</dependencies>

使用此POM时,它不起作用:

When this POM is used, it does not work:

<dependencies>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>redshift.jdbc</artifactId>
        <version>1.1.2.0002</version>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.4-1201-jdbc41</version>
    </dependency>
</dependencies>

是什么让Java选择Redshift驱动程序而不是Postgres驱动程序?

What is making Java choose the Redshift driver rather than the Postgres driver?

(Redshift驱动程序的类路径是 com.amazon.jdbc41.Driver ,所以我认为这不是类路径冲突)

(the Redshift driver's classpath is com.amazon.jdbc41.Driver, so I wouldn't think it's a classpath conflict)

TIA

推荐答案

您的问题是,Java支持 ServiceLoader 使用JDBC 4.0的机制。

Your problem is, that Java supports the ServiceLoader mechanism with JDBC 4.0.

在JDBC 4中, DriverManager 将从 META-INF / services / java.sql.Driver 在他们的jar文件中设置。当您调用 getConnection()时,DriverManager将为给定的jdbc URL选择第一个合适的驱动程序。

In JDBC 4, the DriverManager will find and register drivers from the META-INF/services/java.sql.Driver setting in their jar file. When you call getConnection() the DriverManager will choose the first suitable driver for the jdbc URL given.

现在redshift和postgres驱动程序在jdbc url方面有所不同,但是(引用来自redshift docs ):

Now redshift and postgres driver are different in terms of jdbc url, but (quoting from the redshift docs http://docs.aws.amazon.com/redshift/latest/mgmt/configure-jdbc-connection.html#obtain-jdbc-url):

现在,会发生什么,来自redshift的JDBC驱动程序是通过服务条目加载的,并将自己作为redshift jdbc URL和postgres的驱动程序一个。

Now, what happens, is, that the JDBC driver from redshift is loaded over the service entry and places himself as the driver for the redshift jdbc URL and the postgres one.

我无法准确判断 DriverManager 是否允许通过加载另一个驱动程序来覆盖现有的jdbc-driver-links但解决你的问题ld是显式控件,要么首先加载postgres驱动程序(如果URL只能注册一次),要么在redshift驱动程序之后显式加载它(如果可以覆盖JDBC URL映射)。

I cannot tell exactly if the DriverManager allows overwriting existing jdbc-driver-links by loading another driver, but a solution to your problem could be the explicit control to either load the postgres driver first (if URL will be registered only once) or to explicitly load it after the redshift driver (if JDBC URL mapping can be overwritten).

我不知道,是否有一个属性禁止redshift驱动程序注册postgres URL。

I cannot tell, if there is a property to disallow the redshift driver to register for the postgres URL.

这篇关于使用了错误的JDBC驱动程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-13 11:47