Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jTDS JDBC Driver: getNString() throws error

Tags:

java

jdbc

jtds

I am using the jtDS JDBC driver and when I call ResultSet.getNString(index); I get the following exception:

run:
Exception in thread "main" java.lang.AbstractMethodError: net.sourceforge.jtds.jdbc.JtdsResultSet.getNString(I)Ljava/lang/String;
    at javasql.ProductsController.PrePopulate(ProductsController.java:51)
    at javasql.ProductsController.<init>(ProductsController.java:37)
    at javasql.Program.main(Program.java:25)
Java Result: 1
BUILD SUCCESSFUL (total time: 6 seconds)

When I use getString(index) it works fine.. it's only with getNString() that I am having a problem and the column in my MSSQL table is defined as NVarChar. So, what gives? Does jtDS not support getNString()? Maybe it gets both VarChar and NVarChar via the same getString() function?

EDIT:

Related unicode problem.. I can see that trying to use Unicode doesn't work for inserting either. My column is defined as nvarchar(255) and yet the following INSERT statement does not work:

private final String INSERT_FORMAT = "INSERT INTO Products (Name, Price, QuantityInStock) VALUES (N'%s', %s, %s)";

    public void Insert(Product p) {
            products.add(p);
            try {
                statement.addBatch(String.format(INSERT_FORMAT, p.getName(), p.getPrice(), p.getQuantityInStock()));
            } catch (SQLException ex) {
                System.out.println(ex.getMessage());
            }
        }

public void SaveChanges() {
        try {
            statement.executeBatch();
        } catch (SQLException ex) {
            System.out.println(ex.getMessage());
        }
        RefreshData();
    }

The unicode characters that I input show up as question marks in the database. This normally happens when you forget to prepend N to the said parameter in the insert statement.. but here you can see that I clearly specified it. JtDS' feature list does say it supports NVARCHAR, NTEXT, etc.. but currently I'm only seeing problems. What am I doing wrong?

EDIT 2

Issue 1 is resolved.. I inserted some Chinese characters directly into the database via SSMS and when I used getString(index), it worked fine. So it seems jTDS uses getString for all text types I guess. Strange then it doesnt throw some kind of Unsupported Exception for the getNString(index) function.

So, now we're left with the problem of how to insert unicode data into an NVARCHAR column. Surely someone here has had experience with this?

EDIT 3

I changed my code to use a prepared statement in each method instead of trying to use a batch and used the setInt, setString, etc methods. However, I am still having the same problems... if I use setString() for unicode, it inserts ??? into my db. If I use setNString() then I get the same error that I received at the top of this post when I was doing getNString... This is insane... how could this driver become so popular if it doesn't actually support unicode?? What am I missing here? The site does say it supports NVARCHAR, etc.. so what crazy unintuitive thing is it that I need to do in order to make this work???

like image 602
Matt Avatar asked Sep 25 '12 01:09

Matt


2 Answers

getNString was added with Java 1.6/JDBC 4.0. Looks like your driver is too old.

like image 151
Philippe Marschall Avatar answered Nov 03 '22 04:11

Philippe Marschall


What type is your primary key ? I had exactly the same problem as you are described, that is : I could retrieve the data stored as NVARCHAR using the classic getString() method but the updates would not work, even having set the sendStringParametersAsUnicode option to true... until I changed the primary key from NVARCHAR back to VARCHAR. Now it works for me. The updates did not actually produce any errors, it just appears the primary key could not be found and hence nothing happened... Still, I was hoping to be able to use unicode storage for some fields without setting sendStringParametersAsUnicode option to true, but I am under the impression that it is not possible, unless maybe by typing the concerned columns as byte[] instead of NVARCHAR and setting them using the setBytes() method (as suggested here/)

like image 24
ianbrewer Avatar answered Nov 03 '22 05:11

ianbrewer