views:

614

answers:

1

I have a database table consisting of countries. In my DAO which extends HibernateDAOSupport the following method...

public List<Country> getCountries() {
 return getHibernateTemplate().loadAll(Country.class);
}

...generates the following activity:

Hibernate: update countries set name=?, iso_alpha_2=?, iso_alpha_3=? where id=?
Hibernate: update countries set name=?, iso_alpha_2=?, iso_alpha_3=? where id=?
Hibernate: update countries set name=?, iso_alpha_2=?, iso_alpha_3=? where id=?
...
once for each row

The method works, however. I get my list of countries, but what's with all the updates?

My mapping for this class isn't terribly exotic:

<class name="Country" table="countries">
 <id name="id" column="id">
  <generator class="identity"/>
 </id>
 <property name="name" column="name"/>
 <property name="alpha2" column="iso_alpha_2" />
 <property name="alpha3" column="iso_alpha_3" />
</class>

Can anyone point me in the right direction? Why would loadAll be triggering updates?

+3  A: 

Hibernate apparently thinks that the values it loaded from the DB have changed, so it's flushing the updates.

You can just set 'mutable="false"' in the class mapping, which should stop the updates, but that's not ideal.

Try setting 'dynamic-update="true"' on the class mapping, and that will at least show which column Hibernate thinks needs updating. Are the values in the countries table actually being changed in any way? I think if you set debug logging on the org.hibernate.type package you'll also get debug output showing what values are being bound for the update statements.

This sort of effect can occur if the model object tries to be clever- e.g. trimming whitespace, making a change to the value that the database doesn't preserve.

araqnid
Thanks for the tip on dynamic-update. It looks like the properties causing the problems are character arrays. Now I've got to do some digging and figure out how to map character arrays of specific size... should I just use strings?
Boden
Ah, you were mapping char(2) and char(3) to character arrays of length 2 and 3? I guess you hit the Java feature that arrays don't implement equals() by doing pairwise comparison, only by identity. So when Hibernate looked to see if the duplicated array was equal, it was getting false hits.Yes, I'd recommend using strings. Possibly have your setters throw an IllegalArgumentException if someone tries to set the 2-character code to a 3-character string, for instance.
araqnid
Thanks, I did just that and it works fine. Learn something new every ten minutes around this place! :)
Boden
That's the idea :p
araqnid