I have a table (Merchant) which has a set of Credentials, containing the username/password combinations that are allowed to access that merchant. I have a Merchant object that has been persisted to the database, and I want to create a credential object that relates to that merchant.
I create the credential and call
credential.saveOrUpdate(). This saves the row to the database, but this row is not included in the cached
Merchant.credentials collection.
If I use the
merchant.getCredentials().add( credential ) method, the row is saved to the database, and the row IS included in the cached collection.
I would have expected that both methods would add the credential to the cached collection. Calling
save() could then check if there is a relationship with a cached collection and add itself to that collection.
Is there some way to configure this behaviour that I couldn't find in the documentation, or is this behaviour by design?
btw, I just want to say what a great product Hibernate is. Every time I look at the code to save an object to the database, I'm just so impressed at how much simpler it is than our old framework, or CMP EJB, or especially the bad old days of BMP EJB. Good job the guys!
Hibernate version:
2.1.7c
Mapping documents:
Code:
<hibernate-mapping>
<class name="com.qvalent.test.entity.Merchant" table="Merchant"
optimistic-lock="all" dynamic-update="true">
<cache usage="read-write"/>
<id name="merchantId" type="long" unsaved-value="null">
<column name="ID_Merchant" sql-type="long" not-null="true"/>
<generator class="assigned"/>
</id>
<property name="defaultCurrencyCode" type="string">
<column name="CD_Default_Currency" sql-type="char(3)" not-null="true"/>
</property>
<property name="supplierCode" type="string">
<column name="CD_Supplier" sql-type="char(60)" not-null="true"/>
</property>
<property name="communityCode" type="string">
<column name="CD_Community" sql-type="char(20)" not-null="true"/>
</property>
<property name="communityDescription" type="string">
<column name="DS_Community" sql-type="char(4000)" not-null="true"/>
</property>
<property name="merchantDescription" type="string">
<column name="DS_Merchant" sql-type="char(4000)" not-null="true"/>
</property>
<property name="modifiedDate" type="java.util.Date">
<column name="DT_modified" sql-type="datetime" not-null="true"/>
</property>
<property name="enabled" type="boolean">
<column name="FL_Enabled" sql-type="boolean" not-null="true"/>
</property>
<property name="replicateTransactions" type="boolean">
<column name="FL_Replicate_Transactions" sql-type="boolean" not-null="true"/>
</property>
<set name="credentials" inverse="true" cascade="all" lazy="true" order-by="ID_Credential">
<cache usage="read-write"/>
<key column="ID_Merchant" />
<one-to-many class="com.qvalent.test.entity.Credential" />
</set>
<map name="securityParameters" table="Merchant_Security_Parameter"
inverse="false" cascade="all-delete-orphan" lazy="true">
<cache usage="read-write"/>
<key column="ID_Merchant" />
<index column="NM_Parameter" type="string"/>
<element column="DA_Parameter" type="string"/>
</map>
</class>
<query name="Merchant.all"><![CDATA[
from com.qvalent.test.entity.Merchant as m
]]></query>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.qvalent.test.entity.Credential" table="Credential"
optimistic-lock="all" dynamic-update="true">
<cache usage="read-write"/>
<id name="credentialId" type="long" unsaved-value="null">
<column name="ID_Credential" sql-type="long" not-null="true"/>
<generator class="increment"/>
</id>
<property name="username" type="string">
<column name="CD_Username" sql-type="char(60)" not-null="true"/>
</property>
<property name="password" type="string">
<column name="CD_Password" sql-type="char(60)" not-null="true"/>
</property>
<property name="ipAddress" type="string">
<column name="TX_IP_Address" sql-type="char(4000)" not-null="true"/>
</property>
<property name="certificateText" type="string">
<column name="TX_Certificate" sql-type="char(4000)" not-null="false"/>
</property>
<many-to-one name="merchant" cascade="all" column="ID_Merchant"
class="com.qvalent.test.entity.Merchant"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():Code:
t = sess.beginTransaction();
Merchant dbMerchant =
(Merchant)sess.get( Merchant.class, new Long( 4 ) );
Credential credential = new Credential(
"test", "test", "192.168.40.0/32", null, dbMerchant );
sess.save( credential );
sess.flush();
t.commit();
Full stack trace of any exception that occurs:Name and version of the database you are using:MS SQL Server 2000
The generated SQL (show_sql=true):Code:
Hibernate: select merchant0_.ID_Merchant as ID_Merch1_0_, merchant0_.CD_Default_
Currency as CD_Defau2_0_, merchant0_.CD_Supplier as CD_Suppl3_0_, merchant0_.CD_
Community as CD_Commu4_0_, merchant0_.DS_Community as DS_Commu5_0_, merchant0_.D
S_Merchant as DS_Merch6_0_, merchant0_.DT_modified as DT_modif7_0_, merchant0_.F
L_Enabled as FL_Enabled0_, merchant0_.FL_Replicate_Transactions as FL_Repli9_0_
from Merchant merchant0_ where merchant0_.ID_Merchant=?
Hibernate: insert into Credential (CD_Username, CD_Password, TX_IP_Address, TX_C
ertificate, ID_Merchant, ID_Credential) values (?, ?, ?, ?, ?, ?)
Debug level Hibernate log excerpt: