Hi,
The Problem:
We are facing an issue in which when we are issuing a join query (on two tables), duplicate instances of one class (mapped to one of the table) are loaded.
Observation:We have observed that the final query formed by Hibernate is when picked up and manually fired in database browser (such as MySQL Yog), the output we get is correct, in the sense that all rows are unique with some column value differing in each. But when actual class instances are created from it, we get duplicate instances of them (with even memory id same). So what we end up doing is to create a HashSet out of the List we get and hence get unique values. We think that we may need to apply some specific configuration which we are not aware of it. We have debugged enough but are not able to get a solution. So, we are seeking your guidance for the same.
Below are more details on the problem.
Environment:Hibernate: 3.0
MySQL: 5.0.27
JBoss: 4.0.5.GA
Java: J2SDK 1.4.2_08
Hbm Xml Configuration:Table1: wsc_log, Class: LogRecordCache
Code:
<class name="LogRecordCache" table="wsc_log" lazy="false">
<id name="logId" column="logid" type="long">
<generator class="assigned" />
</id>
<property name="logId" type="long" access="field" update="false" insert="false"/>
<property name="logLevel" column="loglevel" type="int" access="field" />
<component name="serviceAccessInfo" class="ServiceAccessInfo" access="field">
<property name="creationTime" column="creationtime" type="long2date" access="field" />
<property name="ipAddress" column="ipaddress" type="string" access="field" />
<property name="userID" column="userid" type="long" access="field" />
<property name="userLoginId" column="userloginid" type="string" access="field" />
<property name="userGroup" column="usergroup" type="string" access="field" />
<property name="deviceSoftwareClass" column="devicesoftwareclass" type="string" access="field" />
<property name="walletVersion" column="walletversion" type="string" access="field" />
<property name="serviceUrl" column="serviceurl" type="string" access="field" />
<property name="messageNo" column="commserrormsgno" type="int" access="field" />
<property name="message" column="commserrormsg" type="string" access="field" />
<property name="sessionId" column="sessionid" type="string" access="field" />
<property name="serviceName" column="servicename" type="string" access="field" />
<property name="mobileNo" column="mobileno" type="string" access="field" />
<property name="clusteredNodeId" column="clusterednodeid" type="string" access="field" />
<property name="deviceProductName" column="deviceproductname" type="string" access="field" />
<property name="logType" column="logtype" type="string" access="field" />
</component>
<list name="logs" lazy="false" cascade="save-update" inverse="true">
<key property-ref="logId" column="logid"/>
<index column="indexcolumn" type="int"/>
<one-to-many class="LogRecord"/>
</list>
</class>
Table2: wsc_logrecords, Class: LogRecord
Code:
<class name="LogRecord" table="wsc_logrecords">
<id name="logRecordId" column="logrecordid" type="string">
<generator class="uuid.hex"/>
</id>
<property name="timeStamp" column="timestamp" type="long2date" access="field" />
<property name="message" column="message" type="string" access="field" />
<property name="logLevel" column="loglevel" type="int" access="field" />
<many-to-one lazy="false" name="logRecordCache" column="logid" property-ref="logId"/>
<property name="index" column="indexcolumn" type="int" insert="true" update="true" />
</class>
The Actual Queryselect this_.logid as logid2_, this_.logId as logId16_2_, this_.loglevel as loglevel16_2_, this_.creationtime as creation4_16_2_, this_.ipaddress as ipaddress16_2_, this_.userid as userid16_2_, this_.userloginid as userlogi7_16_2_, this_.usergroup as usergroup16_2_, this_.devicesoftwareclass as deviceso9_16_2_, this_.walletversion as walletv10_16_2_, this_.serviceurl as serviceurl16_2_, this_.commserrormsgno as commser12_16_2_, this_.commserrormsg as commser13_16_2_, this_.sessionid as sessionid16_2_, this_.servicename as service15_16_2_, this_.mobileno as mobileno16_2_, this_.clusterednodeid as cluster17_16_2_, this_.deviceproductname as devicep18_16_2_, this_.logtype as logtype16_2_, logrecord1_.logrecordid as logrecor1_0_, logrecord1_.timestamp as timestamp15_0_, logrecord1_.message as message15_0_, logrecord1_.loglevel as loglevel15_0_, logrecord1_.logid as logid15_0_, logrecord1_.indexcolumn as indexcol6_15_0_, logrecordc4_.logid as logid1_, logrecordc4_.logId as logId16_1_, logrecordc4_.loglevel as loglevel16_1_, logrecordc4_.creationtime as creation4_16_1_, logrecordc4_.ipaddress as ipaddress16_1_, logrecordc4_.userid as userid16_1_, logrecordc4_.userloginid as userlogi7_16_1_, logrecordc4_.usergroup as usergroup16_1_, logrecordc4_.devicesoftwareclass as deviceso9_16_1_, logrecordc4_.walletversion as walletv10_16_1_, logrecordc4_.serviceurl as serviceurl16_1_, logrecordc4_.commserrormsgno as commser12_16_1_, logrecordc4_.commserrormsg as commser13_16_1_, logrecordc4_.sessionid as sessionid16_1_, logrecordc4_.servicename as service15_16_1_, logrecordc4_.mobileno as mobileno16_1_, logrecordc4_.clusterednodeid as cluster17_16_1_, logrecordc4_.deviceproductname as devicep18_16_1_, logrecordc4_.logtype as logtype16_1_
from wsc_log this_ inner join wsc_logrecords logrecord1_ on this_.logid=logrecord1_.logid left outer join wsc_log logrecordc4_ on logrecord1_.logid=logrecordc4_.logid where (lower(this_.logtype) like ?) and (lower(this_.logtype) like ?)
order by this_.creationtime asc
Can you please help us by letting us know what details we are missing or what additional configuration/coding we need to do so as to solve this problem?
Thank You,
Rupesh Bhadeshiya.