Well I checked the creation code and tried to set also applicationKey of CardReaderAppKey instance (which I left empty before), then persist the object. Further mentioned criteria returned object with not null application key. So it seems that I did not understand way of correct object creation under hibernate. I thought as long as I set the simple properties:
Code:
tokenId, appId, keyId, appKeyId
setting applicationKey property is not neccessery. Everything is run under one hibernate session (junit test with empty DB at start).
Just in case I am wrong here are required listings (before above described change):
ApplicationKey mapping Code:
<class name="ApplicationKey" table="hsm_appkey">
<composite-id mapped="true">
<key-property name="tokenId" column="token_id"/>
<key-property name="appId" column="app_id"/>
<key-property name="keyId" column="key_id"/>
<key-property name="appKeyId" column="appkey_id"/>
</composite-id>
<property name="validFrom" update="false">
<column name="valid_from" not-null="true" default="current_timestamp"/>
</property>
<many-to-one name="key" class="Key" insert="false" update="false" not-null="true" unique="true" foreign-key="FK_APPKEY_KEY">
<column name="token_id"/>
<column name="key_id"/>
</many-to-one>
<many-to-one name="application" class="Application" insert="false" update="false" not-null="true" unique="true" foreign-key="FK_APPKEY_APP">
<column name="token_id"/>
<column name="app_id"/>
</many-to-one>
</class>
Here is the setter signature:Code:
public void setApplicationKey(ApplicationKey aApplicationKey)
Application key insertionCode:
ApplicationKey app = new ApplicationKey();
app.setAppId(aAppId);
app.setTokenId(tokenId);
app.setAppKeyId(aAppKeyId);
app.setValidFrom((aValidFrom == null) ? Calendar.getInstance()
: aValidFrom);
app.setKeyId(key.getId());
_dao.persist(app);
------------------
2007-08-21 12:20:14,260 DEBUG () [main] org.hibernate.SQL -
insert
into
test.hsm_appkey
(valid_from, token_id, app_id, key_id, appkey_id)
values
(?, ?, ?, ?, ?)
2007-08-21 12:20:14,260 DEBUG () [main] org.hibernate.jdbc.AbstractBatcher - preparing statement
2007-08-21 12:20:14,268 DEBUG () [main] org.hibernate.persister.entity.AbstractEntityPersister - Dehydrating entity: [sk.prosoft.hsm.pojo.ApplicationKey#component[tokenId,appId,keyId,appKeyId]{appId=KUTEST, tokenId=0, appKeyId=1, keyId=KEY_1}]
2007-08-21 12:20:14,269 DEBUG () [main] org.hibernate.type.CalendarType - binding '2007-08-21 12:20:04' to parameter: 1
2007-08-21 12:20:14,270 DEBUG () [main] org.hibernate.type.IntegerType - binding '0' to parameter: 2
2007-08-21 12:20:14,270 DEBUG () [main] org.hibernate.type.StringType - binding 'KUTEST' to parameter: 3
2007-08-21 12:20:14,271 DEBUG () [main] org.hibernate.type.StringType - binding 'KEY_1' to parameter: 4
2007-08-21 12:20:14,271 DEBUG () [main] org.hibernate.type.IntegerType - binding '1' to parameter: 5
Here is the criteria used:Code:
DetachedCriteria.forClass(CardReaderAppKey.class)
.add(Restrictions.eq("cardReader", new CardReader(aCardReaderId)))
.add( Restrictions.eq("appKeyId", aAppKeyId))
.add(Restrictions.eq("appId", aAppId))
.createCriteria("applicationKey").addOrder( Order.desc("validFrom"));
CardReaderAppKey creationCode:
ApplicationKey appkey = ...;
_currentCrak = new CardReaderAppKey();
_currentCrak.setTokenId(new Integer((int) _cao.getTokenId()));
_currentCrak.setCardReader(_cardReader);
_currentCrak.setAppId(appkey.getAppId());
_currentCrak.setAppKeyId(appkey.getAppKeyId());
_currentCrak.setKeyId(appkey.getKeyId());
_currentCrak.setConfirmed(true);
_dao.persist(_currentCrak);
2007-08-21 12:46:37,260 DEBUG () [main] org.hibernate.SQL -
insert
into
test.hsm_cardreader_appkey
(key_id, confirmed, token_id, app_id, appkey_id, cr_id)
values
(?, ?, ?, ?, ?, ?)
2007-08-21 12:46:37,260 DEBUG () [main] org.hibernate.jdbc.AbstractBatcher - preparing statement
2007-08-21 12:46:37,265 DEBUG () [main] org.hibernate.persister.entity.AbstractEntityPersister - Dehydrating entity: [sk.prosoft.hsm.pojo.CardReaderAppKey#component[tokenId,appId,appKeyId,cardReader]{appId=KUTEST, tokenId=0, cardReader=sk.prosoft.hsm.pojo.CardReader#14031980, appKeyId=1}]
2007-08-21 12:46:37,265 DEBUG () [main] org.hibernate.type.StringType - binding 'KEY_1' to parameter: 1
2007-08-21 12:46:37,266 DEBUG () [main] org.hibernate.type.BooleanType - binding 'true' to parameter: 2
2007-08-21 12:46:37,266 DEBUG () [main] org.hibernate.type.IntegerType - binding '0' to parameter: 3
2007-08-21 12:46:37,266 DEBUG () [main] org.hibernate.type.StringType - binding 'KUTEST' to parameter: 4
2007-08-21 12:46:37,266 DEBUG () [main] org.hibernate.type.IntegerType - binding '1' to parameter: 5
2007-08-21 12:46:37,266 DEBUG () [main] org.hibernate.type.LongType - binding '14031980' to parameter: 6
Here is the query listing log:Code:
DEBUG SQL -
select
this_.token_id as token1_4_1_,
this_.app_id as app2_4_1_,
this_.appkey_id as appkey3_4_1_,
this_.cr_id as cr4_4_1_,
this_.key_id as key5_4_1_,
this_.confirmed as confirmed4_1_,
applicatio1_.token_id as token1_3_0_,
applicatio1_.app_id as app2_3_0_,
applicatio1_.appkey_id as appkey3_3_0_,
applicatio1_.key_id as key4_3_0_,
applicatio1_.valid_from as valid5_3_0_
from
test.hsm_cardreader_appkey this_
inner join
test.hsm_appkey applicatio1_
on this_.token_id=applicatio1_.token_id
and this_.app_id=applicatio1_.app_id
and this_.appkey_id=applicatio1_.appkey_id
and this_.key_id=applicatio1_.key_id
where
this_.cr_id=?
and this_.appkey_id=?
and this_.app_id=?
order by
applicatio1_.valid_from desc
DEBUG AbstractBatcher - preparing statement
DEBUG IdentifierValue - id unsaved-value strategy UNDEFINED
DEBUG LongType - binding '14031980' to parameter: 1
DEBUG IntegerType - binding '2' to parameter: 2
DEBUG StringType - binding 'KUTEST' to parameter: 3
DEBUG AbstractBatcher - about to open ResultSet (open ResultSets: 0, globally: 0)
DEBUG Loader - processing result set
DEBUG Loader - result set row: 0
DEBUG IntegerType - returning '0' as column: token1_3_0_
DEBUG StringType - returning 'KUTEST' as column: app2_3_0_
DEBUG IntegerType - returning '2' as column: appkey3_3_0_
DEBUG StringType - returning 'KEY_2' as column: key4_3_0_
DEBUG IntegerType - returning '0' as column: token1_4_1_
DEBUG StringType - returning 'KUTEST' as column: app2_4_1_
DEBUG IntegerType - returning '2' as column: appkey3_4_1_
DEBUG LongType - returning '14031980' as column: cr4_4_1_
DEBUG DefaultLoadEventListener - loading entity: [sk.prosoft.hsm.pojo.CardReader#14031980]
DEBUG DefaultLoadEventListener - entity found in session cache
DEBUG Loader - result row: EntityKey[sk.prosoft.hsm.pojo.ApplicationKey#component[tokenId,appId,appKeyId,keyId]{appId=KUTEST, tokenId=0, appKeyId=2, keyId=KEY_2}], EntityKey[sk.prosoft.hsm.pojo.CardReaderAppKey#component [tokenId,appId,appKeyId,cardReader]{appId=KUTEST, tokenId=0, cardReader=sk.prosoft.hsm.pojo.CardReader#14031980, appKeyId=2}]
DEBUG Loader - done processing result set (1 rows)
As you can see mapping is correct (I mean ApplicationKey is fetched from DB). None of my pojo objects has any final method, and they have at least default constructor (so CGLib should work). One correction I use hibernate 3.2.5.ga