Hi everyone,
I use
Spring with hibernate 3.1.3. I have a project where I have 'Rule' entities, profiles and endpoints. The assiciation between them is that a profile can contain several rules. And an endpoint can contain multiple endpoints.
Now because the endpoint object are frequently accessed (and it must go fast), I keep them in memory together with their rules and profiles. So they are probably detached objects.
Now the problem is that the profile can be enabled or disabled. When I load a profile from the database and save it with saveOrUpdate(), the profile is indeed updated in the database but the detached object I keep in memory are not. (pretty logical).
So I decided to add equals and hashcode to rule and profile where JVM identiy == DB identity (just to be sure, if it works I'll change it) so that when I update something, hiberate would hopefuly know they are the same ojects and update them too. But it does not.
Then I added a version column to the profile, So that hibernate knows which is the latest profile. The versioning number gets incremented when I do an update, but I'm still stuck with the previous version of the object in memory.
Now when I get the endpoints (with rules and profiles) from my application memory, I noticed their are select being executed in the background by hibernate, but I still receive an old version of the profile.
Now I now that if I do session.merge(), I could get the new version of the objects, but I'm actually not really capable of calling it every time I access the enpoints in memory. (because they are accessed a lot) (and also note that and endpoint object has also non persistent fields. The profile is actually the only thing that can get updated.)
A dirty worksaround could be to iterate over the endpoints, the rules, and update the profiles there too. But I was hoping for a better hibernate solution.
Thank you,
Hibernate mappings:
Rule
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="be.kdg.climatControl.model.endpoints.rules.Rule" table="t_rule">
<synchronize table="t_profile"/>
<id type="integer" name="id" unsaved-value="0">
<generator class="increment"/>
</id>
<discriminator column="type" type="string" />
<property name="conditionsToBeValid" type="integer" not-null="true"/>
<property name="type" type="java.lang.String" length="20" insert="false" update="false" not-null="true" />
<set name="actions" cascade="all" inverse="true" lazy="false">
<key column="ruleId"/>
<one-to-many class="be.kdg.climatControl.model.endpoints.rules.actions.RuleActionWrapper"/>
</set>
<set name="conditions" cascade="all" inverse="true" lazy="false">
<key column="ruleId"/>
<one-to-many class="be.kdg.climatControl.model.endpoints.rules.conditions.ConditionWrapper"/>
</set>
<many-to-one name="profile" column="profileId" lazy="false" cascade="merge"/>
</class>
</hibernate-mapping>
ProfileCode:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="be.kdg.climatControl.model.endpoints.rules.Profile" table="t_profile">
<id type="integer" name="id" unsaved-value="0">
<generator class="increment"/>
</id>
<version name="versionNumber"
type="integer"
unsaved-value="undefined"
generated="never"
insert="true"
/>
<property name="name" type="java.lang.String" length="50" not-null="true"/>
<property name="active"/>
<set name="rules" cascade="merge, save-update" inverse="true" lazy="false">
<key column="profileId"/>
<one-to-many class="be.kdg.climatControl.model.endpoints.rules.Rule"/>
</set>
</class>
</hibernate-mapping>
[/code]