Issue Details (XML | Word | Printable)

Key: NUCRDBMS-822
Type: Bug Bug
Status: Closed Closed
Resolution: Fixed
Priority: Trivial Trivial
Assignee: Unassigned
Reporter: eran
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
DataNucleus Store RDBMS

possible bug in org.datanucleus.store.rdbms.mapping.datastore.BigIntRDBMSMapping

Created: 11/Aug/14 10:03 PM   Updated: 12/Aug/14 10:41 AM   Resolved: 12/Aug/14 08:36 AM
Component/s: Queries
Affects Version/s: 4.0.0.release
Fix Version/s: 4.0.2

Datastore: MySQL
Severity: Production


 Description  « Hide
while debugging, I came across the following code in
possible bug in org.datanucleus.store.rdbms.mapping.datastore.BigIntRDBMSMapping.setObject(PreparedStatement ps, int param, Object value):

...
 else if (value instanceof String)
                {
                    String s = (String) value;
                    ps.setInt(param, s.charAt(0));
                }
...

it might not be the root cause of the problem I had (seem to be a bug also in google sql driver) but had the code been something like:
 else if (value instanceof String)
                {
                    Long l = Long.parseLong(s);
                    ps.setInt(param, l.longValue());
                }
there would be no problem. why is the code the way it is? is it a bug?
thank you



Andy Jefferson made changes - 12/Aug/14 08:34 AM
Field Original Value New Value
Priority Major [ 3 ] Trivial [ 5 ]
Andy Jefferson added a comment - 12/Aug/14 08:36 AM
Why it was like that you would need to talk to the person who contributed it; 99% of users would never want to persist a String into an INTEGER column, so don't see such things. GitHub master changes it

Andy Jefferson made changes - 12/Aug/14 08:36 AM
Status Open [ 1 ] Resolved [ 5 ]
Fix Version/s 4.0.2 [ 12235 ]
Resolution Fixed [ 1 ]
eran added a comment - 12/Aug/14 09:59 AM
I didn't try to persist a string manually either.
I was trying to run with google app engine which uses google sql driver.
For some reason (possibly a bug) com.google.cloud.sql.jdbc.PreparedStatement.geteGeneratedKeys
returns a String type instead of Long for a primary-key-auto-generated-Long column. Since datanucleus uses getGeneratedKeys, it misinterpreted the result and there were severe implications. Take following scenario for instance:

1.having an object A with a list of B elements, mapped using foreign key
2. inserting a new item to the B table is performed by datanucleus in two stages:
executing an INSERT statement, and then executing an UPDATE statement to update the foreign key and index columns of the mapping to the A parent entry
3. the UPDATE statement WHERE clause parameter is populated using getGeneratedKeys of the INSERT statement.
4. since the returned value is of type String and not Long, datanucleus misinterprets it and generates a wrong Long value.
5. since the WHERE clause parameter is wrong the B entry is not found and not updated.
6. B entry foreign key column remains null and querying entity A returns with an empty list of B (since no B is referencing A).

anyway, thank you for the quick response

Eran


Andy Jefferson added a comment - 12/Aug/14 10:24 AM
FWIW Google Cloud SQL would work perfectly fine with MySQL official driver (according to their docs), and there is no "possibly" in what you describe about Google's getGeneratedKeys returning string for a Long column - that is where the real problem is.

Andy Jefferson made changes - 12/Aug/14 10:29 AM
Status Resolved [ 5 ] Closed [ 6 ]
eran added a comment - 12/Aug/14 10:41 AM
I've read the docs an tried many options.
even when setting
properties.setProperty("javax.jdo.option.ConnectionDriverName",
"com.mysql.jdbc.Driver");
the implementation being eventually called by datanucleus is google's. not sure how but
it could be due to the fact you have to set a url which implicates the use of google cloud sql, e.g "jdbc:google:rdbms://<host>:3306/<db_name>".
Any other setting doesn't work (google throws some access denial exception or some of the sort) and it makes sense - google specifically declare they won't permit any code other than theirs opening sockets or accessing files.
I reported the getGeneratedKeys problem to them, providing a very simple code (direct use of their driver, no jdo/datanucleus at all) which shows the problem. waiting for their response...