]
Gail Badner commented on HHH-3338:
----------------------------------
Hi Michael, thanks for the heads-up about this. The new ordering for union clauses is due
to changes in how HashMap and HashSet are iterated in JDK 1.6. The column order in union
clauses should be in the same order in which they are mapped, so this is definitely a bug.
I'm looking into several other differences that I'm seeing in SQL executed by the
unit tests when running JDK 1.6 vs JDK 1.5.
If you (or anyone else) is interested in taking a shot at the fix, please take a look at
org.hibernate.persister.entity.UnionSubclassEntityPersister.generateSubquery(). It gets
the columns from org.hibernate.mapping.Table.getColumnIterator(), which returns an
iterator on the values of a org.apache.commons.collections.SequencedHashMap. This iterator
should return the columns in the order they were mapped. The problem is that they are
added to a HashSet, which is later iterated to create the union clause.
It would also help to add tests that assert that the columns are in the correct order. It
looks like this should be possible in a unit test in org.hibernate.test.hql, although I
haven't looked into the best place to put it.
Order of attributes in generated SQL query is dependent on Java
version
-----------------------------------------------------------------------
Key: HHH-3338
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3338
Project: Hibernate3
Issue Type: Bug
Components: core
Affects Versions: 3.2.6
Environment: WIndows XP, Java 5 Update 15, Java 6 update 5
Reporter: Michael Gerz
We use Hibernate Core 3.2.6 in combination with Derby 10.4.1.3.
When migrating from Java 5 to Java 6, we noticed a huge performance hit. Our analysis has
unveiled that Hibernate 3.2.6 produces semantical identical but syntactically different
queries for Java 5 and Java 6.
Java 5:
Hibernate: select logevent0_.ID as ID7_, logevent0_.INDEX_SENT as INDEX2_7_,
logevent0_.TEST_RUN_ID as TEST3_7_, logevent0_.SENDER as SENDER7_, logevent0_.TIME_SENT as
TIME5_7_, logevent0_.MESSAGE as MESSAGE8_, logevent0_.SEVERITY as SEVERITY8_,
logevent0_.SERIALIZED_CONTENT as SERIALIZED1_11_, logevent0_.RECEIVER as RECEIVER11_,
logevent0_.TIME_RECEIVED as TIME3_11_, logevent0_.INDEX_RECEIVED as INDEX4_11_,
logevent0_.ACTION_REQUEST as ACTION1_13_, logevent0_.ACTION_REPLY as ACTION1_14_,
logevent0_.clazz_ as clazz_ from ( select TEST_RUN_ID, SENDER, MESSAGE, SEVERITY,
nullif('x','x') as SERIALIZED_CONTENT, nullif('2000-1-1
00:00:00','2000-1-1 00:00:00') as TIME_RECEIVED, ID,
nullif('x','x') as ACTION_REQUEST, TIME_SENT,
nullif('x','x') as ACTION_REPLY, nullif('x','x') as
RECEIVER, nullif(0,0) as INDEX_RECEIVED, INDEX_SENT, 2 as clazz_ from USER_LOG_EVENT union
all select TEST_RUN_ID, SENDER, MESSAGE, SEVERITY, nullif('x','x') as
SERIALIZED_CONTENT, nullif('2000-1-1 00:00:00','2000-1-1 00:00:00') as
TIME_RECEIVED, ID, nullif('x','x') as ACTION_REQUEST, TIME_SENT,
nullif('x','x') as ACTION_REPLY, nullif('x','x') as
RECEIVER, nullif(0,0) as INDEX_RECEIVED, INDEX_SENT, 3 as clazz_ from DEVEL_LOG_EVENT
union all select TEST_RUN_ID, SENDER, nullif('x','x') as MESSAGE,
nullif('x','x') as SEVERITY, nullif('x','x') as
SERIALIZED_CONTENT, nullif('2000-1-1 00:00:00','2000-1-1 00:00:00') as
TIME_RECEIVED, ID, ACTION_REQUEST, TIME_SENT, nullif('x','x') as
ACTION_REPLY, nullif('x','x') as RECEIVER, nullif(0,0) as INDEX_RECEIVED,
INDEX_SENT, 6 as clazz_ from ACTION_REQUEST_LOG_EVENT union all select TEST_RUN_ID,
SENDER, nullif('x','x') as MESSAGE, nullif('x','x') as
SEVERITY, nullif('x','x') as SERIALIZED_CONTENT, nullif('2000-1-1
00:00:00','2000-1-1 00:00:00') as TIME_RECEIVED, ID,
nullif('x','x') as ACTION_REQUEST, TIME_SENT, ACTION_REPLY,
nullif('x','x') as RECEIVER, nullif(0,0) as INDEX_RECEIVED, INDEX_SENT, 7
as clazz_ from ACTION_REPLY_LOG_EVENT union all select TEST_RUN_ID, SENDER,
nullif('x','x') as MESSAGE, nullif('x','x') as SEVERITY,
SERIALIZED_CONTENT, TIME_RECEIVED, ID, nullif('x','x') as ACTION_REQUEST,
TIME_SENT, nullif('x','x') as ACTION_REPLY, RECEIVER, INDEX_RECEIVED,
INDEX_SENT, 4 as clazz_ from DATA_FLOW_LOG_EVENT ) logevent0_ where
logevent0_.TEST_RUN_ID=?
Java 6:
Hibernate: select logevent0_.ID as ID7_, logevent0_.INDEX_SENT as INDEX2_7_,
logevent0_.TEST_RUN_ID as TEST3_7_, logevent0_.SENDER as SENDER7_, logevent0_.TIME_SENT as
TIME5_7_, logevent0_.MESSAGE as MESSAGE8_, logevent0_.SEVERITY as SEVERITY8_,
logevent0_.SERIALIZED_CONTENT as SERIALIZED1_11_, logevent0_.RECEIVER as RECEIVER11_,
logevent0_.TIME_RECEIVED as TIME3_11_, logevent0_.INDEX_RECEIVED as INDEX4_11_,
logevent0_.ACTION_REQUEST as ACTION1_13_, logevent0_.ACTION_REPLY as ACTION1_14_,
logevent0_.clazz_ as clazz_ from ( select nullif('x','x') as RECEIVER,
TIME_SENT, SEVERITY, nullif('2000-1-1 00:00:00','2000-1-1 00:00:00') as
TIME_RECEIVED, ID, SENDER, MESSAGE, TEST_RUN_ID, nullif('x','x') as
SERIALIZED_CONTENT, INDEX_SENT, nullif(0,0) as INDEX_RECEIVED,
nullif('x','x') as ACTION_REQUEST, nullif('x','x') as
ACTION_REPLY, 2 as clazz_ from USER_LOG_EVENT union all select
nullif('x','x') as RECEIVER, TIME_SENT, SEVERITY, nullif('2000-1-1
00:00:00','2000-1-1 00:00:00') as TIME_RECEIVED, ID, SENDER, MESSAGE,
TEST_RUN_ID, nullif('x','x') as SERIALIZED_CONTENT, INDEX_SENT,
nullif(0,0) as INDEX_RECEIVED, nullif('x','x') as ACTION_REQUEST,
nullif('x','x') as ACTION_REPLY, 3 as clazz_ from DEVEL_LOG_EVENT union
all select nullif('x','x') as RECEIVER, TIME_SENT,
nullif('x','x') as SEVERITY, nullif('2000-1-1
00:00:00','2000-1-1 00:00:00') as TIME_RECEIVED, ID, SENDER,
nullif('x','x') as MESSAGE, TEST_RUN_ID, nullif('x','x')
as SERIALIZED_CONTENT, INDEX_SENT, nullif(0,0) as INDEX_RECEIVED, ACTION_REQUEST,
nullif('x','x') as ACTION_REPLY, 6 as clazz_ from ACTION_REQUEST_LOG_EVENT
union all select nullif('x','x') as RECEIVER, TIME_SENT,
nullif('x','x') as SEVERITY, nullif('2000-1-1
00:00:00','2000-1-1 00:00:00') as TIME_RECEIVED, ID, SENDER,
nullif('x','x') as MESSAGE, TEST_RUN_ID, nullif('x','x')
as SERIALIZED_CONTENT, INDEX_SENT, nullif(0,0) as INDEX_RECEIVED,
nullif('x','x') as ACTION_REQUEST, ACTION_REPLY, 7 as clazz_ from
ACTION_REPLY_LOG_EVENT union all select RECEIVER, TIME_SENT,
nullif('x','x') as SEVERITY, TIME_RECEIVED, ID, SENDER,
nullif('x','x') as MESSAGE, TEST_RUN_ID, SERIALIZED_CONTENT, INDEX_SENT,
INDEX_RECEIVED, nullif('x','x') as ACTION_REQUEST,
nullif('x','x') as ACTION_REPLY, 4 as clazz_ from DATA_FLOW_LOG_EVENT )
logevent0_ where logevent0_.TEST_RUN_ID=?
The first order (using Java 5) looks more reasonable, because TEST_RUN_ID is the first
column in all of the tables and it is also a foreign key.
The changed order of attributes does not really explain why Derby performs so poor on
Java 6 and we have already issued a report to the Derby community.
Nevertheless, the SQL queries generated Hibernate should not depend on a specific version
of Java. Maybe a compareTo() method is missing somewhere in the code...?
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: