We've got an application using spring for making calls to DB2 stored procedures.
The application was working fine with jdbc version 1.XX.XX (and DB2 V8). An recent upgrade to DB2 V9 moves us to using jdbc versiong 3.58.90 instead.
However, this seems to have broken the named parameters mapping in spring (version 2.5.5). Some previously working code had call string
call storedproc123(:id,:date)
now throws exceptions with
[jcc][t4][10427][12544][3.58.90] Error parsing FLOAT literal value starting at index 19. Error Detail:Unexpected character ':' found in FLOAT literal.
...
ERRORCODE=-4463, SQLSTATE=42601
...
Has anyone encountered something similar?
Thanks in advance!
---edited to add more info---
I've tried swapping the old jdbc back after the upgrade. The application works just fine with the old driver, however we'd like to upgrade to the newer version since another app on the same server needs this newer jdbc, and it's difficult to have different versions of the same jdbc deployed on our server (we uses JBoss).
http://redneckprogrammer.blogspot.com/2009/10/running-multiple-versions-of-oracle.html discussed how to deploy multiple versions of the same JDBC driver, however this seems to be too much of a hack and I'd like to avoid it if at all possible.
Found the cause, see IBM patch PK87567 .
...
All Connectivity: Driver code has been enhanced to support
a new API on com.ibm.db2.jcc.DB2ParameterMetaData:
getParameterMarkerNames, which returns a list of parameter
marker names used in the SQL Statement as a String .
This method returns null if property
enableNamedParameterMarkers is set to
DB2BaseDataSource.NOT_SET or DB2BaseDataSource.NO, or if
there are no named parameter markers in the SQL Statement.
The list returned contains unique parameter marker names.
If a named parameter marker appears more than once in the
SQL Statement, it will only appear once in the list
returned. (120191)
...
Fixed the problem by enabling the marker.
Related
I am facing this weird issue with spring Jdbc Template when used for Oracle DB.
JDK version- 11.0.3
ojdbc8 version- 12.2.0.1
Spring jdbc version-2.2.4.RELEASE
DB- Oracle- 12c
Issue:
When I call update() method on Jdbc Template, sometimes it does not return number of updated rows and returns '0' instead.
When I run same code with in memory db such as H2, it goes smooth.
I checked queries very closely and they are looking fine.
The issue was with the handling of the CHAR datatype in Oracle.
Oracle was doing right padding for this datatype and Jdbc query was failing for equality check cause of that(in SQL query 'WHERE' clause where I was using this field).
The use of RTRIM function in Query at the java side resolved this issue.
I have a application where I used these technologies:
Grails 3.3.0
JDK 1.8
Spring 4+
Mysql 8
GORM 6.1.6.RELEASE
org.grails.plugins:spring-security-core:3.2.0
Hibernate 5+
Problem is when I am trying to connect the application with Mysql 8(with 5.6+ it is working fine), I am not able to get the information related to user from Grails-Spring-Security plugin.
The application is running even connect to DB but wont be able to authenticate or fetch the information of the User like findByUsername where username is property in my user domain class.
I have User domain class defined in application.properties file.
grails.plugin.springsecurity.userLookup.userDomainClassName = 'com.aaa.User'
At some point I found this error but not sure whether it is related to this or not.
java.lang.IllegalStateException:
Either class [com.aaa.User] is not a domain class or GORM has not been initialized correctly or has already been shutdown.
Ensure GORM is loaded and configured correctly before calling any methods on a GORM entity.
Want to understand why it wont be able to fetch the information from DB. I have tried lot of things like change the GORM version to 6.1.7 and grails spring-secuirty-core plugin version but not able to get anything.
Any help would be appreciated.
Thanks,
Atul
We are able to solve the issue. It happens when grails-hibernate plugin look for the property(in my case its username as I am calling API findByUsername) which is present in the static api or not. If it is not there it throws the exception.
The thing worked for me is, I have to put the property in static mapping of User domain class:
static mapping = {
table 'userTable'
id column: 'id'
password column: 'userpassword'
username column: 'username'
}
I am not sure why it is happening, when I run the application with Mysql5.6+ its working.(The driver is according to it) but when go with Mysql8, it look for the property in static mapping.
One more point I would like to mention to fix the issue is, make sure you have tablename, columnname same as defined in DB. Case sensitivity is what expected.
As I mentioned the case sensitivity, if you are using linux with Mysql8, the lower_case_table_names=0, this check with the following as per Mysql official documentation:
Table and database names are stored on disk using the lettercase
specified in the CREATE TABLE or CREATE DATABASE statement. Name
comparisons are case sensitive. You should not set this variable to 0
if you are running MySQL on a system that has case-insensitive file
names (such as Windows or macOS). If you force this variable to 0 with
--lower-case-table-names=0 on a case-insensitive file system and access MyISAM tablenames using different lettercases, index corruption
may result.
So if the table name is static is in camel or upper case and in db it is lower case it wont match. and the error occurred.
Hope this helps to someone.
I maintain a piece of software that runs as a Servlet and can make use of MySQL, Oracle or SQL Server as the DB backend - depending on what the Customer wants to use.
Everything works perfectly with MySQL and Oracle, and SQL Server works great too, except I cannot insert/update Unicode sequences into the database.
I can do a manual insert in SQL Server Management Studio of a unicode sequence like this
INSERT INTO mytable (msg) VALUES (N'Modern Standard Hindi (मानक हिन्दी), is a standardised and Sanskritised register of the Hindustani language.')
This data is output in my software correctly, so this verifies that the database and the web front end can both handle unicode no problem.
And here's my connection string
jdbc:jtds:sqlserver://<server ip>:1433/MyDb
As I said, Oracle and MySQL work perfectly using this setup. What's different about SQL Server?
Note: I also tried the official Microsoft-provided JDBC driver with exactly the same results.
If it makes a difference, I'm using JPA Repositories to do my DB interactions. The whole webapp is also set up as a SpringMVC application.
Edit: I also tried adding useUnicode=true;characterEncoding=UTF-8 to the end of my connection string with the same results
You may need to specify in your connection string that you're using Unicode, and also what encoding you're using. Maybe something like this?
jdbc:jtds:sqlserver://<server_ip>:1433;databaseName=MyDb;useUnicode=true;characterEncoding=UTF-8
So there was one thing I left off my original question.
I had the system set up with Spring Security and a CharacterEncodingFilter in the filter chain to force UTF-8 in all requests and responses, but I had it set up in the afterSpringSecurityChain section of my web security initializer.
I moved the filter into the beforeSpringSecurityChain method and boom - everything UTF-8 works perfectly with all DB vendors.
I ended up not adding any params to my connection string or anything either. It was literally just the filter that I changed.
I am writing a Java application using Hibernate and IBM DB2 9.7 LUW for database. I am using the SQLQuery API to read a custom SQL query string and execute it against the DB. The query contains aliases, i.e. SELECT WORK.EMPLOYEE AS WORKEMPLOYEE, just as an example.
When retrieving the result set from DB with list() command, the resulting map does not contain the alias as key. So writing map.containsKey("WORKEMPLOYEE") returns false. I also tried using query.setResultTransformer(AliasToEntityMapResultTransformer.INSTANCE) but it did not change the situation.
I don't know Hibernate, but I suspect this is a symptom of an issue we've seen regarding DB2 LUW and aliases.
It relates to the distinction between a column's "name" and its "label". IBM document the behaviour at this page, which suggests that the behaviour will be different with different versions of the database driver.
Specifically, this paragraph:
Whether a column in the SELECT list of a query has an AS clause. For JDBC drivers before the IBM Data Server Driver for JDBC and SQLJ Version 4.0, if a column in the SELECT list of a query contains an AS clause,ResultSetMetaData.getColumnNamereturns the argument of the AS clause. Under the IBM Data Server Driver for JDBC and SQLJ Version 4.0,ResultSetMetaData.getColumnNamereturns the table column name.
suggests that you are seeing the behaviour that you (and I) regard as faulty because you are using a version 4+ driver.
There are three possible solutions, none of which is entirely satisfactory.
Use a version 3.x driver.
You can switch to calling getColumnLabel on the ResultSetMetaData. That would give you the correct result with DB2 LUW using version 4+ drivers. This applies to our version of the problem, but might not be relevant or possible via Hibernate.
There is a property which you can set on the DataSource or Connection object: useJDBC4ColumnNameAndLabelSemantics would need to be set to DB2BaseDataSource.NO. However, I don't know whether you can set that via Hibernate. If you can, it should make aliases behave the old (and propert) way.
In our environment we haven't decided yet on how best to deal with this. We're working around it using option 1 for the moment. I'm inclined to use option 2, but we have to suport multiple DB platforms, and I'm not sure how it will work with the others. For option 3, we're sing Spring, so it may not be practical to set that property.
I recently upgraded HSQL from 1.8.0.10 to 2.0 and then 2.0.1.rc3 without any changes in my code or test data. I have lots of tests which previously worked and now i am getting lots of exceptions involving "casting"...
Caused by: org.hsqldb.HsqlException: data exception: invalid character value for cast
Unfortunately the exception messages are poor and give me next to no clue which column etc is bad.
Other exceptions show that it is attempting to complain the sysadmin username to a long ??
Caused by: org.hsqldb.HsqlException: incompatible data type in conversion: from SQL type VARCHAR to java.lang.Long, value: SA
at org.hsqldb.error.Error.error(Error.java:77)
... 54 more
The really strange this is i am using HSQL in memory mode and start it up empty and never set any access stuff.
PS
I have also updated Hibernate to 3.6.
I just ran into a similar issue, after upgrading to HSQLDB 2.2.9, some unit tests started failing with this error message:
java.sql.SQLSyntaxErrorException: incompatible data type in conversion: from SQL type VARCHAR to java.math.BigDecimal, value: SA
The issue was only present when using DBUnit to manipulate datasets, there was no problem when using Hibernate. After turning up the JDBC logging, I found that DBUnit was failing after a select like this:
select id, user from MYTABLE order by id
// then, SQLSyntaxErrorException when DBUnit tried to retrieve the 'user' column:
BigDecimal userId = resultSet.getBigDecimal(2);
This answer led me to the cause: DBUnit does not escape the 'user' keyword by default, which explains why the error message has the value "SA", which is the default HSQLDB system user. However, DBUnit does let you configure escaping, which fixed the problem.
Finally the reason that Hibernate wasn't having problems was that its generated SQL is more explicit, e.g.
select mytable0.id, mytable0.user from MYTABLE mytable0 order by mytable0.id
Summary:
Find out which library isn't escaping keywords in SQL statements!
Auto casting behaviour has become more strict in version 2.x. This may account for the problems, but it is impossible to say where without seeing the actual table definitions and the statement executed by Hibernate. The extensive Hibernate test suite runs with very few (and unrelated) errors with the latest HSQLDB RC.
We ran into this same problem when packaging a custom version of hsqldb (required to fix this issue Hibernate/hsqldb 2 Cannot Hydrate Blob Column)
The current hsqldb source jars include an old version of org.hibernate which does not correctly identify the hsqldb version (ironic). If this source is included in your build then it may override the actual hibernate 3.6 version of the class.
Check inside of your hsqldb jar dependency and see if it includes any org.hibernate classes
Or try putting the following in your code to see where the dialect being used is coming from:
System.out.println(
new HSQLDialect().getClass().getProtectionDomain().getCodeSource());