Closed GoogleCodeExporter closed 8 years ago
Could you post a simple, standalone test case that reproduces the problem? It
would
be great if the test case does not have any dependencies except the H2 jar file
and
Hibernate (a simple Java class that is run using a static main method). Please
include any initialization code (CREATE TABLE, INSERT and so on) in the Java
class.
Original comment by thomas.t...@gmail.com
on 4 Oct 2009 at 9:14
Tomas, I tried but failed to reproduce this bug.
But under debugger I noticed what caused the problem.
In trigger I insert some info into Z_HISTORY table.
Z_HISTORY has and ID column on sequence
ID BIGINT DEFAULT (NEXT VALUE FOR PUBLIC.SEQ_Z_HISTORY) NOT NULL
NULL_TO_DEFAULT
SEQUENCE PUBLIC.SEQ_Z_HISTORY
and Z_HISTORY has a primary key
ALTER TABLE PUBLIC.Z_HISTORY ADD CONSTRAINT PUBLIC.PK_Z_HISTORY PRIMARY KEY(ID);
So, after trigger finished THE WRONG IDENTITY RETURNED to hibernate
instead of ID of newly inserted _Card_ the ID of newly inserted Z_HISTORY
inserted
and after that FK_CONSTRAINT fire the exception, because there no card with
such ID.
It seems that H2 return LAST generated by ANY sequence ID, may be it is Ok, but
what
if something was generated inside trigger?
So as temporary workaround I remove ID column from Z_HISTORY table, and now all
works fine.
This bug is very critical for me :(.
P.S. I don't understand why I have this bug in my app, but don't have from
JUnit
test case...
Original comment by kua...@gmail.com
on 4 Oct 2009 at 11:51
Finally, I do it.
I understand why my test case don't show the bug :)
Because, Z_HISTORY has no rows and returned generated ID was good for inserting.
Now I set sequence for Z_HISTORY at 1000 and the bug appeared.
In attach Eclipse project with test case.
To run it you need Hibernate hibernate-3.3.2.GA and slf4j + some slf4j
implementation, I use logback, you may use another.
And one more: you should configure paths in test and in hibernate.cfg.xml
I write about it in test code comments.
It was a real hunt :) for a bug.
Original comment by kua...@gmail.com
on 4 Oct 2009 at 1:25
Hello, Thomas.
Have you try my test case? This problem is quite critical for me.
I need to know it is H2 or Hibernate bug and try to find out workaround.
Original comment by kua...@gmail.com
on 5 Oct 2009 at 2:10
> Have you try my test case?
No, I didn't have time yet. I'm sorry.
Original comment by thomas.t...@gmail.com
on 7 Oct 2009 at 7:03
Hello, Thomas.
If you have time, please look my test case.
This bug (or may be feature) is very important for me.
Original comment by kua...@gmail.com
on 11 Oct 2009 at 9:43
Hello, Thomas.
I just interesting - have you try my test case?
Original comment by kua...@gmail.com
on 29 Oct 2009 at 2:43
Hi,
Sorry, I didn't have time yet... Could you upload the dependencies somewhere
please?
It takes a lot of time just downloading all the jar files from the different
projects... Sorry, I know I'm lazy... but I guess you have the libraries
already, so
maybe if you have time, could you zip them and upload them somewhere? That
would be
great!
Regards,
Thomas
Original comment by thomas.t...@gmail.com
on 3 Nov 2009 at 7:40
hi! I upload all dependencies to:
http://rapidshare.com/files/302129110/h2_test_deps.rar.html
I hope this time you fix the bug :)
------------------
Alexey
Original comment by kua...@gmail.com
on 4 Nov 2009 at 3:16
This will be fixed in the next release.
Original comment by thomas.t...@gmail.com
on 5 Nov 2009 at 8:17
Some more details: The problem is that the generated value for "owner.id" is
lost.
This happens as follows:
- You insert a row into "owner", the identity value becomes 1.
- The triggers inserts a row into "z_history", the identity becomes 1000.
- Hibernate calls getGeneratedKeys(), which now returns 1000 (that's wrong of
course)
A workaround is not to use getGeneratedKeys (I think you can configure that in
Hibernate). Another workaround is to 'reset' the identity value in the trigger.
It's
really just a hack:
+ "CREATE SEQUENCE FUZZ;\n"
public void fire(Connection conn, Object[] oldRow, Object[] newRow) throws
SQLException {
ResultSet rs = conn.createStatement().executeQuery("CALL IDENTITY()");
rs.next();
long identity = rs.getLong(1);
rs.close();
...
PreparedStatement ins = conn
.prepareStatement("INSERT INTO PUBLIC.Z_HISTORY (OLD_VALUE,
NEW_VALUE) VALUES (?, ?)");
ins.setString(1, "foo");
ins.setString(2, "bar");
ins.execute();
...
conn.createStatement().execute("ALTER SEQUENCE FUZZ RESTART WITH " + identity
+ "; CALL NEXT VALUE FOR FUZZ");
}
This should work (it did for me). The real solution is to implement
SCOPE_IDENTITY()
and use this for getGeneratedKeys(). I have now implemented this.
Original comment by thomas.t...@gmail.com
on 5 Nov 2009 at 8:20
>> You insert a row into "owner", the identity value becomes 1.
>> The triggers inserts a row into "z_history", the identity becomes 1000.
>> Hibernate calls getGeneratedKeys(), which now returns 1000 (that's wrong of
course)
Yes. You are right, actually I try to describe this behavior in comments #2 &
#3.
It would be grate if you implement SCOPE_IDENTITY(), because I don't really
want to
hacking around this problem. It would be great if it works "out of the box".
----------------
Alexey
Original comment by kua...@gmail.com
on 6 Nov 2009 at 5:28
Should be fixed with version 1.2.123
Original comment by thomas.t...@gmail.com
on 8 Nov 2009 at 1:30
Original issue reported on code.google.com by
kua...@gmail.com
on 4 Oct 2009 at 6:57