Re: com.mysql.jdbc.UpdatableResultSet.updateBlob gives AbstractMethodError



pjvleeuwen@xxxxxxxxx wrote:
ResultSet.TYPE_FORWARD_ONLY,
....
resultset.first();
<http://java.sun.com/javase/6/docs/api/java/sql/ResultSet.html#first()>
Returns:
true if the cursor is on a valid row; false if there are no rows in the result set

You don't check the return code. This might not matter here, but you should be aware of it.

Throws:
SQLException - if ... this method is called on a ... result set type ... TYPE_FORWARD_ONLY

Which is what you typed your ResultSet.


PreparedStatement pstmt = con
.prepareStatement("INSERT INTO `image` (`house_id`,
`image`) "
+ "VALUES(1, ?)");
pstmt.setBlob(1, new URL( // <===============line 51
"http://www.woonnet-haaglanden.nl/library/fotos/18/12845.jpg"; )
.openStream());
pstmt.executeUpdate();

Exception in thread "main" java.lang.AbstractMethodError:
com.mysql.jdbc.ServerPreparedStatement.setBlob(ILjava/io/
InputStream;)V
at nl.vanleeuwenwilmot.housing.search.woonnet.app.Test.main(Test.java:
51)

This is pretty much the same error you got with the ResultSet.

And if I try setObject like the following I get no error at 51, but a
null-pointer exception after reading it.

public static void main(String[] args) throws IOException,
SQLException {

Connection con = null;
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();

You don't need the newInstance(). You could also do the forName() call in a static initializer.

....

PreparedStatement pstmt = con
.prepareStatement("INSERT INTO `image` (`house_id`,
`image`) "
+ "VALUES(1, ?)");
pstmt.setObject(1, new URL(
"http://www.woonnet-haaglanden.nl/library/fotos/18/12845.jpg";)
.openStream());
pstmt.executeUpdate();

Statement readstmt = null;
readstmt =
con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);

ResultSet resultset = readstmt.executeQuery("SELECT * FROM
`image` " //
+ "WHERE `house_id` = 1;");
resultset.first();

This time it's with a ResultSet.TYPE_SCROLL_INSENSITIVE, but you still should consider using next() instead, and you must check the return code!

InputStream theimage =
resultset.getBlob("image").getBinaryStream();

Image image = ImageIO.read(theimage);

// Use a label to display the image
JFrame frame = new JFrame();
JLabel label = new JLabel(new ImageIcon(image)); // <=== line
69
frame.getContentPane().add(label, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}

Exception in thread "main" java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(ImageIcon.java:161)
at nl.vanleeuwenwilmot.housing.search.woonnet.app.Test.main(Test.java:
69)


Further more I tried reading the inputstream

That's "InputStream".

to a string (and playignorant on charset headaches), but I couldn't get that to work...
(furthermore, it doesn't seem the right way to go).

It isn't, but byte[] would be all right.

The AbstractMethodError only occurs if the implementing class for the abstract call is not available or incompatible at run time. Something isn't finding the MySQL-specific implementation of these methods. I'd review how you have the MySQL JAR located in your classpath.

It's a weird one, because a classpath issue shows up at compile time, or worst case, at runtime when the Class.forName() fails. How you could get to the MySQL Driver class and not have access to its implementation classes is a mystery.

There's a clue, however, at the MySQL web site:
<http://dev.mysql.com/doc/refman/5.0/en/connector-j-installing-classpath.html>
where the tell you to put the JAR

mysql-connector-java-[version]-bin.jar

in your classpath, but you've got

mysql-connector-java-5.0.3.jar

I downloaded the latest Connector/J (version 5.0.7) and there was only the *-bin.jar version, not the version without the "-bin".

--
Lew
.