I have a many to many relationship solved with a join table.
My business requirements are such that there exists a many to many relationship between user and technology. This is resolved with the table user_technology.
So whenever I want to associate a user to a technology what I essentially need to do is an insert into the user_technology table. My code for that follows (with spring framework):
public void saveTechnologyForUser(final UserVO user, final TechnologyVO tech) {
HibernateTemplate template = getHibernateTemplate();
template.execute(
new HibernateCallback(){
public Object doInHibernate(Session session) throws HibernateException {
user.addTechnology(tech);
session.update(user);
log.info("Saved user with email " + user.getEmail());
return null;
}
}
);
}
What ends up happening is that hibernate does 4 queries. It updates the user table, it updates the technology table, it deletes from the join table (user_technology) based on the user_id and then it inserts into the user_technology table the user id and technology id. This seems like way too much work for what amounts to just an insert into the join table. Is there a way to do this so that you can get hibernate to just do an insert into the join table without the other queries. The other queries are un-necessary for my needs. On top of that, I need to keep the user's data in the join table and therefore I can't have hibernate delete it and then reinsert based on the user id. This is because a user may be associated to more than one technology
My mapping docs are below. The Technology object knows nothing about Users. I wanted Users to manage the relationship.
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="com.securance.vo.SecuranceUserVO"
table="auditapp_user"
dynamic-update="false"
dynamic-insert="false"
>
<id
name="userId"
column="user_id"
type="java.lang.Integer"
>
<generator class="native">
</generator>
</id>
<property
name="businessEntity"
type="java.lang.String"
update="true"
insert="true"
column="business_entity"
/>
<property
name="firstName"
type="java.lang.String"
update="true"
insert="true"
column="first_name"
/>
<property
name="lastName"
type="java.lang.String"
update="true"
insert="true"
column="last_name"
/>
<property
name="password"
type="java.lang.String"
update="true"
insert="true"
column="password"
/>
<property
name="phoneNumber"
type="java.lang.String"
update="true"
insert="true"
column="phone_number"
/>
<property
name="subscribed"
type="char"
update="true"
insert="true"
column="subscribed"
/>
<set
name="techs"
table="user_technology"
lazy="true"
inverse="false"
cascade="all"
sort="unsorted"
>
<key
column="user_id"
/>
<many-to-many
class="com.securance.vo.TechnologyVO"
column="tech_id"
outer-join="auto"
/>
</set>
<property
name="email"
type="java.lang.String"
update="true"
insert="true"
column="email"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-SecuranceUserVO.xml
containing the additional properties and place it in your merge dir.
-->
</class>
<query name="findByEmailAndPassword"><![CDATA[
from SecuranceUserVO user where user.email = :email and user.password = :password
]]></query>
</hibernate-mapping>
Any help with this is greatly appreciated.
Thanks
|