I have a (so far) simple application with subscribers and attributes associated to subscribers. My mapping is as follows:
Code:
<class name="Subscriber" table="subscriber">
<id name="subscriberId" unsaved-value="-1">
<generator class="native" />
</id>
<property name="username" type="string" />
<set name="attributes" lazy="true" cascade="all">
<key column="subscriberId" />
<one-to-many class="SubscriberAttribute" />
</set>
</class>
<class name="SubscriberAttribute" table="subscriber_attribute">
<id name="attributeId" unsaved-value="-1">
<generator class="native" />
</id>
<property name="attrKey" type="string" />
<property name="attrValue" type="string" />
<many-to-one name="subscriber" class="Subscriber"
column="subscriberId" not-null="true" cascade="none" />
</class>
In my java code I do (simplified a bit to make it short):
Code:
Subscriber s = new Subscriber(-1, "username");
Set attributes = new HashSet();
attributes.add(new SubscriberAttribute(-1, key1, value1);
attributes.add(new SubscriberAttribute(-1, key2, value2);
attributes.add(new SubscriberAttribute(-1, key3, value3);
s.setAttributes(attributes);
session.save(s);
After I run the code, subscriber is added and all the attributes as well. But what troubles is the way they are created (I know this for sure because I have set profileSql=true in my JDBC settings):
1. a new row is inserted in the subscriber table:
insert into subscriber ...
2. id is fetched from the DB:
SELECT LAST_INSERT_ID()
3. a row to subscriber_attribute table is inserted three times and after each insert id is fetched from the DB:
insert into subscriber_attribute (attrKey, attrValue, subscriberId) values ('key1', 'value1', 1)
SELECT LAST_INSERT_ID()
insert into subscriber_attribute (attrKey, attrValue, subscriberId) values ('key2', 'value2', 1)
SELECT LAST_INSERT_ID()
insert into subscriber_attribute (attrKey, attrValue, subscriberId) values ('key3', 'value3', 1)
SELECT LAST_INSERT_ID()
4. each row inserted in 3. is then updated:
update subscriber_attribute set subscriberId=1 where attributeId=1
update subscriber_attribute set subscriberId=1 where attributeId=2
update subscriber_attribute set subscriberId=1 where attributeId=3
What makes the rows in subscriber_attribute to be updated in the end? I can see no reason for that, the subscriberId is already set when the rows were inserted.
Is there any way to have Hibernate insert the rows (in subscriber_attribute) in one query rather than inserting them one by one?
I'm using Hibernate 2.0.3 and MySQL (with INNODB).