Hans
Hans

Reputation: 165

jtds.jdbc.JtdsConnection.createBlob java.lang.AbstractMethodError

mvn:net.sourceforge.jtds/jtds/1.3.1-patch-20190523/jar to save to a Microsoft SQL Server database. Actually this JDBC driver is provided by Talend. For various reasons, I have some Java JDBC code which saves blobs to the database. This works fine with an Oracle DB.

try (Connection con = DriverManager.getConnection(this.connectionString, this.user, this.pw)) {

        insert(con, ags, snr, productVersion, nummer, inhalt, this.migrationsBenutzer, format, daten);
}

public long insert(Connection con,  String ags, String snr, int productVersion ,int nummer,String inhalt, String benutzer, String format, byte[] daten) throws SQLException {
    long result = 0;
    String timestamp = now();
    try {
        Blob blob = con.createBlob();
        blob.setBytes(1, daten);
        PreparedStatement ps = con.prepareStatement(this.insert);
        ...
        ps.setBlob(9, blob);
        result = ps.executeUpdate();

However when I call the method with a connection string for jtds: jdbc:jtds:sqlserver://:1433;databaseName=

I get this exception

Exception in thread "main" java.lang.AbstractMethodError
    at net.sourceforge.jtds.jdbc.JtdsConnection.createBlob(JtdsConnection.java:2776)
    at de.iteos.dao.BildspeichernDAO.insert(BildspeichernDAO.java:60)

What can I do? If feasible I want to keep the method a generic as possible. Do I have to switch to another JDBC driver? I have read somewhere that this could be solved with a validation query. For this I would have to implement two different DataSources for Oracle and SQL Server right?

Upvotes: 0

Views: 931

Answers (1)

Mark Rotteveel
Mark Rotteveel

Reputation: 109001

The problem is that jTDS is - as far as I know - no longer maintained, and available versions are stuck on JDBC 3.0 (Java 1.4) support. The method Connection.createBlob you're trying to call was introduced in JDBC 4.0 (Java 6). Attempts to call this method on a driver that was compiled against the JDBC 3.0 API will result in AbstractMethodError as the method from JDBC 4.0 (or higher) is not implemented.

The simplest and best solution is probably to switch to the Microsoft SQL Server JDBC driver.

Alternatively, you need to switch to the JDBC 3.0 options for populating a blob, that is, using the PreparedStatement.setBinaryStream(int, InputStream, int) method (not to be confused with setBinaryStream(int, InputStream) or setBinaryStream(int, InputStream, long) introduced in JDBC 4.0!), or possibly setBytes(int, byte[]), or using driver specific methods for creating blobs.

The validation query solution you mention doesn't apply here, that solves a problem with Connection.isValid that the data source implementation in some Tomcat versions calls by default, unless you configure a validation query. It has the same underlying cause (the isValid method was also introduced in JDBC 4.0).

I'm not sure what you mean with "I would have to implement two different DataSources for Oracle and SQL Server right?", you cannot use one and the same data source for two different databases, so you would need to configure two different instances anyway.

Upvotes: 1

Related Questions