MySQL JDBC connector string truncation - java

When accessing MySQL through JDBC, the following exception was thrown from the jdbc connector (5.1.39).
Value '\u000248$2ef8cd3c-e4d7-4ad5-8d60-504f6e7db07a\u00132016-11-21
17:26:37\u00132016-11-21
17:26:37\u0010ABCDEFGH\n2016-08-01\n2016-08-16\u0007SOMETHING\u00012\u00041481\u00011\u00042016\b50016387\u000b01026940427\u0012company
XYZ???\u00012$17b9f783-a7c2-4d49-bbc1-8ad73479a0b6\u00132016-11-13
13:31:26\u00132016-11-21
17:44:00\u00011\u00041481\u001bXXXXXXXXXXX\u000bcompanya\u000b00662850544\u000eabcd#email.com\bregular\u000248$57eff2d9-35e0-415a-81e4-04797192133f\u00132016-11-13
13:35:35\u00132016-11-22
14:40:03\u00072361.93\u000248\u0003EUR\u00011\bSTATUS?\n2016-12-31\n2017-03-09?\u00011\u000283\u00185828d21111000070071715f2\u000248\u000b0.001937241\u000b0.037620570\u000b0.120000000\u000b0.052392000\u000b1.000000000\u00010\u00010\u00010\u00010\u00010\u000b0.037620570\u000b0.001414463\u000b0.004799110\u00011\u00012\u00011\u000248\u000e348.743925612\f19.186074388\u000b0.012392000\u000b0.001574005\u000b0.004008749\u00010\u0000\u00130000-00-00
00:00:00\u00130000-00-00
00:00:00\u00010\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'
can not be represented as java.sql.Timestamp
This looks like the JDBC driver cannot correctly determine the end of strings in the result row. Our table are in latin1.
Is there anything that should be done on the connection level to prevents these issues?

The issue was solved upgrading from 5.7.11 a 5.7.26. Lesson learned: do not underestimate the importance of minor releases

Related

DB2 ERRORCODE 4499 SQLSTATE=58009

On our production application we recently become weird error from DB2:
Caused by: com.ibm.websphere.ce.cm.StaleConnectionException: [jcc][t4][2055][11259][4.13.80] The database manager is not able to accept new requests, has terminated all requests in progress, or has terminated your particular request due to an error or a force interrupt. ERRORCODE=-4499, SQLSTATE=58009
This occurs when hibernate tries to select data from one big table(More than 6 milions records and 320 columns).
I observed that when ResultSet lower that 10 elements, hibernate selects successfully.
Our architecture:
Spring 4.0.3
Hibernate 4.3.5
DB2 v10 z/Os
Websphere 7.0.0.31(with JDBC V9.7FP5)
This select works when I tried to executed this in Data Studio or when app is started localy from Tomcat(connected to production Data Source). I suppose that Data Source on Websphere is not corectly configured, but I tried some modifications and without results. I also tried to update JDBC Driver but that not helped. Actually I become then ERRORCODE = -1244.
Ok, so now I'm looking for any help ;).
I can obviously provide additional information when needed.
Maybe someone fighted earlier with this problem?
Thanks in advance!
We have the same problem and finally solved by running REORG and RUNSTAT on the table(s). In our case, databse and tables were damaged and after running both mentioned operations, it resolved.
This occurs when hibernate tries to select data from one big table(More than 6 milions records and 320 columns)
6 million records with 320 columns seems huge to be read at once through hibernate. How you tried creating a database cursor and streaming few records at a time? In plain JDBC it is done as follows
Statement stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_READ_ONLY);
stmt.setFetchSize(50); //fetch only 50 records at a time
while with hibernate you would need the below code
Query query = session.createQuery(query);
query.setReadOnly(true);
query.setFetchSize(50);
ScrollableResults results = query.scroll(ScrollMode.FORWARD_ONLY);
// iterate over results
while (results.next()) {
Object row = results.get();
// process row then release reference
// you may need to flush() as well
}
results.close();
This allows you to stream over the result set, however Hibernate will still cache results in the Session, so you’ll need to call session.flush() every so often. If you are only reading data, you might consider using a StatelessSession, though you should read its documentation beforehand.
Analyze the database table locking impact when using this approach.

How to specify Fastload utility for jdbc:odbc?

My connection string looks like this
String cn = "jdbc:odbc:DSN";
it works fine . However, when i try to modify it to
String cn = "jdbc:odbc:DSN, TYPE=FASTLOAD";
it does not establish connection
I also tried
String cn = "jdbc:odbc:DSN, TYPE=FASTLOADCSV";
Teradata's JDBC driver supports the FastLoad protocol, but you're not using it. You try to connect via JDBC-ODBC bridge, change to jdbc:teradata://...
Try
String cn = "jdbc:odbc:DSN; TYPE=FASTLOAD";
If you want to connect with ODBC, then use semicolons. But if you want to use FastLoad, then you need to connect using JDBC, in which case you should use commas and the forward slash like so:
String cn = "jdbc:teradata://servername/TYPE=FASTLOADCSV";
Also, you'll need to disable auto-committing whenever you fastload (at least if you do batch inserting, which you probably should). Fastload requires an empty table; committing causes the table to be non-empty. To prevent that issue, simply set autocommit to False before inserting, and set it back to True (or whatever you want it to be) after all inserts have been executed and committed.
Alternatively, you can pursue a different approach: commit stuff, but use staging tables. With this method you create new, empty tables for each insert batch. In the end you can consolidate those tables into one with the MERGE operation. If you do this process right, you can avoid any rewriting of data on disk. (Source: this other SO question)
More information:
Teradata JDBC tips on improving performance
Sample code from Teradata about JDBC, with boilerplate code on connectivity, CRUD, etc.
More Teradata docs on connectivity with JDBC

Java MySQL PreparedStatement.setBoolean wraps value in quotes

Short version of my question is:
PreparedStatement ps;
ps = connection.prepareStatement("Insert into T values (?)");
ps.setBoolean(1, true);
ps.executeUpdate();
What can be the reasons for this code sample to produce query with value wrapped in quotes?
Long version of my question is:
I have JavaEE application with plain JDBC for DB interactions and recently I noticed that there are some MySQLDataTruncation exceptions appearing in my logs. These exceptions were occurring on attempt to save entity into DB table which have boolean column defined as BIT(1). And it was because generated query looked like this:
Insert into T values ('1');
Note that value is wrapped with quotes. Query was logged from application with Log4J log.info(ps); statement.
Previous logs demonstrate that there where no quotes.
Furthermore, even MySQL server logs started to look different. Before this happened I had given pairs of records for each query executed:
12345 Prepare Insert into T values (?)
12345 Execute Insert into T values (1)
And after:
12345 Query Insert into T values ('1')
It is worth noting that those changes wasn`t a result of deploying new version of application or even restarting MySQL/Application server and code, responsible of query generation, is as straightforward as example in this question.
Application server restart fixed the issue for about 12 hours, and then it happened again. As a temporary solution I changed BIT columns to TINYINT
P.S. Examining both aplication and MySQL logs allowed to narrow down the time span when something went wrong to about 2 minutes, but there were nothing abnormal in the logs in this period.
P.P.S. Application server is Glassfish 2.1.1, MySQL server version is 5.5.31-1~dotdeb and MySQL Connector/J version is 5.0.3.
Well, it turned out it was actually an issue with unclosed prepared statements.
When opened statements count at MySQL server reached its allowed maximum, application was still able to continue working somehow, withoout producing sql error:
Error Code: 1461 Can’t create more than max_prepared_stmt_count statements
But in that mode it started to wrap boolean values with quotes, causing all my troubles affecting BIT(1) columns.

Is there a way to config MySQL Connector J driver to insert empty string as 0 to decimal/integer field?

I have a requirement to upgrade company's db legacy system from MySQL ver 4.1 to ver 5.5 ,I currently found out that if i insert empty string to decimal/integer field via java program ,It will throw exception but if i write the same statement and insert it directly via mysql command line the record will be inserted normally(the empty field will become 0),so this lead me to think that there are some problem with jdbc driver , is driver enforce some rule upon statement before pass it to db? i really dont want to re-write the old program to support this change.
thx in advance for your answer :)
You can assign value null not empty string.
You are changing your DB version so all codes may support. So you have to change

Retrieve column Default with Derby DB via JDBC

I have a table with a column defined like this:
Country VARCHAR(2) NOT NULL DEFAULT 'US'
When I try to detect this default with JDBC it fails. Basically when I use DatabaseMetaData.getColumns the result does not contain the COLUMN_DEFAULT column. It is there when I try this with H2.
Any ideas how to get the default with Derby?
Did you try for COLUMN_DEFAULT? Or for COLUMN_DEF? According to the Javadoc I think it should be COLUMN_DEF.
Also, what version of Java and of JDBC are you using? I think that Derby only added COLUMN_DEF as part of the JDBC 4.0 support, which may require Java 1.6.

Categories