EvidentSolutions / dalesbred

Dalesbred - a database access library for Java
https://dalesbred.org
MIT License
54 stars 15 forks source link

ResultSetUtils throws a DatabaseException when a JDBC driver returns byte[] as the column class name in ResultSetMetaData #54

Closed solita-ville-autio closed 7 months ago

solita-ville-autio commented 7 months ago

This happens for example with MariaDB Connector/J 3.x that returns byte[] as the column class name for BINARY type columns instead of [B like older 2.7.x series driver. Class.forName(className) throws a ClassNotFoundException when called with just byte[] and hence ResultSetUtils always fails in instantiator lookup in these situations.

Following repository demonstrates both the issue and one possible workaround: https://github.com/solita-ville-autio/dalesbred-mariadb-connectorj3

Requires JDK 17 and Docker to run. Also tested with JDK 21 just for posterity.

I won't submit a pull request at this point due to the small runtime performance loss that comes from the String equality check, but on the other hand I can't really think of many other alternatives either besides using a try-catch block instead that is probably even more costly when the exception has to be handled. Maybe some kind of Map based cache for Class instances could also yield general performance improvements by avoiding repeated ClassLoader lookups in the spirit of this Hazelcast pull request: https://github.com/hazelcast/hazelcast/pull/8405/files (https://github.com/hazelcast/hazelcast/issues/1162)

komu commented 7 months ago

Wow, that really sucks. I wonder if it does the same for other arrays as well. That is, is [Ljava.lang.String; changed to java.lang.String[] and so on.

Well, given that receiving other arrays is quite rare and this is a real problem, I'll just fix this specific thing for now. A single string-comparison is such a cheap operation in comparison to all the other reflection stuff that I won't even add any flag for it.

Anyway, thanks for the detailed report!

komu commented 7 months ago

I released 1.3.6 with this fix.