2015-08-11 16 views
5

Mam problem, że nie jestem do końca pewien, jak rozwiązać: Mam aplikację internetową (zapakowaną jako wojnę), a klienci mogą skonfigurować, która baza danych chciałbym wskazać. Obsługujemy zarówno PostgreSQL, jak i Redshift (jak również inne). Sterowniki JDBC4 ładowane są automatycznie, co jest dobre. Oto problem:Redshift i Postgres Sterownik JDBC przechwytują ciąg połączenia Jdbc: // Postgresql

Wygląda na to, że sterownik JSBC Redshift odpowie na ciąg połączenia jdbc: // postgresql przed PostgreSQL. Powoduje to błędy JDBC podczas łączenia się z bazą danych PostgreSQL.

Określam nazwę sterownika "org.postgresql.Driver" jako sterownik dla źródła danych w moim pliku pom.xml, ale nie jestem pewien, w jaki sposób wiosenne szablony JDBC wybierają sterownik (chyba że wybiera on pierwszy przewodnik).

Czy ktoś jeszcze ma podobny problem?

Odpowiedz

2

Dzieje się tak, ponieważ sterownik redshift rejestruje się jako obsługujący zarówno prefiks adresu URL jdbc:postgresql, jak i jdbc:redshift.

Gdy sterowniki PostgreSQL & są ładowane ze swoich słoików, każdy rejestruje się w DriverManger.

Logika wdrożona w DriverMananger.getDriver() i DriverManager.getConnection() polega na przechodzeniu w pętlę przez każdy ze sterowników i zatrzymuje się, gdy kierowca wykaże, że jest w stanie obsłużyć podany adres URL.

Jeśli sterownik PostgreSQL rejestruje się jako pierwszy, wszystko działa poprawnie, ponieważ sterownik Postgres próbuje tylko obsłużyć jdbc:postgresql. Jeśli sterownik Redshift udaje się zarejestrować jako pierwszy, sterownik Postgres nigdy nie zostanie użyty.

Jedynym sposobem, zorientowali się rozwiązać tego celu jest dodanie:

static { 
    // Put the redshift driver at the end so that it doesn't 
    // conflict with postgres queries 
    java.util.Enumeration<Driver> drivers = DriverManager.getDrivers(); 
    while (drivers.hasMoreElements()) { 
     Driver d = drivers.nextElement(); 
     if (d.getClass().getName().equals("com.amazon.redshift.jdbc41.Driver")) { 
      try { 
       DriverManager.deregisterDriver(d); 
       DriverManager.registerDriver(d); 
      } catch (SQLException e) { 
       throw new RuntimeException("Could not deregister redshift driver"); 
      } 
      break; 
     } 
    } 
} 
+0

Używamy szablony Wiosna JDBC, czy istnieje sposób, aby określić dla DataSource sterownika, który powinien być używany? Myślałem, że widziałem coś jak setDriver() na kierowniku Kierowcy, ale jestem trochę noobem wiosny ... –

+0

Nie jestem zaznajomiony ze sprężyną, więc nie jestem pewien. Jeśli wiosna po prostu używa DriverManagera za sceną, myślę, że zmiana kolejności sterowników powinna załatwić sprawę. –

5

Innym rozwiązaniem byłoby dodanie „OpenSourceSubProtocolOverride = true” ciąg połączenia JDBC dla regularnych połączeń PostgreSQL.

Przykład:

jdbc:postgresql://localhost:5432/postgres?OpenSourceSubProtocolOverride=true 
+0

to naprawiono dla mnie dodanie do istniejących adresów URL do PG db. – jhnclvr

Powiązane problemy