I have pretty simple model with User object having a map of IdentityAttributes. (see mapping below).
When I create a User and add an IdentityAttribute then save User.
I first see Insert for IdentityAttribute and then when transaction commited Update for the same IdentityAttribute. Update actually "establishes" relationship with User (updates foreign key for User in IdentityAttribute table).
When I delete an IdentityAttribute from map in User. I first see update which "breaks relationship" and then delete for Identity Attribute ( I have cascade="delete-orphan").
Is it normal ?
Thanks a lot for help, Alexi
Details.
1. Creation code
Code:
Session sess = startTxAndSess();
User user = new User("testUser");
String attr1Name = "TestAttrName";
IdentityAttribute attr = new IdentityAttribute(attr1Name);
user.addAttribute(attr);
System.out.println("About to save identity");
sess.saveOrUpdate(user);
Long userId = user.getId();
System.out.println("About to commit");
commitTx();
Debug log which shows extra update. Note that insert into IdentityAttribute does not insert foreign key column identityId. Update does that.
Code:
StartTX:org.springframework.transaction.support.DefaultTransactionStatus@48f675 Sess:2920707
About to save identity
2007-02-10 01:30:57,921 DEBUG [org.hibernate.SQL] - <insert into Identity (id, name, parentId, email, identityType) values (null, ?, ?, ?, 'USER')>
2007-02-10 01:30:57,937 DEBUG [org.hibernate.SQL] - <call identity()>
2007-02-10 01:30:57,953 DEBUG [org.hibernate.SQL] - <insert into IdentityAttributeName (id, name) values (null, ?)>
2007-02-10 01:30:57,953 DEBUG [org.hibernate.SQL] - <call identity()>
About to commit
2007-02-10 01:30:57,968 DEBUG [org.hibernate.SQL] - <update IdentityAttributeName set identityId=?, name=? where id=?>
CommitTX:org.springframework.transaction.support.DefaultTransactionStatus@48f675
2. Delete code
Code:
sess = startTxAndSess();
User u = (User) sess.load(User.class, userId);
System.out.println("Found user");
Map attrMap = u.getAttributeMap();
System.out.println("About to remove");
attrMap.remove(attr1Name);
commitTx();
Debug output again shows first update to IdentityAttribute to set identityId =null to "break" connection to User. Then delete
Code:
StartTX:org.springframework.transaction.support.DefaultTransactionStatus@9fe84e Sess:5009874
Found user
2007-02-10 01:38:07,421 DEBUG [org.hibernate.SQL] - <select user0_.id as id7_0_, user0_.name as name7_0_, user0_.parentId as parentId7_0_, user0_.email as email7_0_ from Identity user0_ where user0_.id=? and user0_.identityType='USER'>
About to remove
2007-02-10 01:38:07,421 DEBUG [org.hibernate.SQL] - <select attributem0_.identityId as identityId1_, attributem0_.id as id1_, attributem0_.name as name1_, attributem0_.id as id8_0_, attributem0_.name as name8_0_ from IdentityAttributeName attributem0_ where attributem0_.identityId=?>
2007-02-10 01:38:07,500 DEBUG [org.hibernate.SQL] - <delete from IdentityAttributeValue where identityAttributeNameId=?>
2007-02-10 01:38:07,500 DEBUG [org.hibernate.SQL] - <update IdentityAttributeName set identityId=null, name=null where identityId=?>
2007-02-10 01:38:07,500 DEBUG [org.hibernate.SQL] - <delete from IdentityAttributeName where id=?>
CommitTX:org.springframework.transaction.support.DefaultTransactionStatus@9fe84e
Don't know if it is related to the problem, but Select from IdentityAttribute above has all fields repeated twice in Select clause. Why is that ? Is it a problem
Mapping
Code:
<class name="Identity" table="Identity" discriminator-value="IDENTITY">
<id name="id"
column="id">
<generator class="native"/>
</id>
<discriminator column="identityType" type = "string" />
<property name="name" column="name" />
<map name="attributeMap" cascade="save-update,delete, delete-orphan" lazy="true" >
<key column="identityId" />
<map-key type="java.lang.String" column="name" />
<one-to-many class="IdentityAttribute" />
</map>
<many-to-one
name="parent"
column="parentId"
class="Identity"
/>
<subclass name="User" discriminator-value="USER">
<property name="email" column="email"/>
</subclass>
<subclass name="Organization" discriminator-value="ORG">
</subclass>
</class>
<class name="IdentityAttribute" table="IdentityAttributeName">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="name" column="name" />
<set name="values" table="IdentityAttributeValue" order-by="value" cascade="all">
<key column = "identityAttributeNameId" />
<element type="java.lang.String" column="value"/>
</set>
</class>