Hi,
First of all I would like to say that hibernate is a superb framework and we have been using it for a while now with great success. Thank you for that!
Now we have encountered some problems, that probably are of our own fault, and because our specific requirements. Maybe somebody out there have som suggestions on a solution.
We are using the Lightweight Class pattern described in :
http://www.hibernate.org/41.html
We are using Hibernate 2.1.2 and the db is FireBird 1.5.
We get a net.sf.hibernate.WrongClassException when doing a 2 simple select statements.
The mappings are of the form:
Code:
<class name="eg.ClassA" table="a" polymorphism="explicit">
...
<many-to-one name="Article" class="eg.ClassBLight">
<column name="b_id" sql-type="char(16)" not-null="false"/>
</many-to-one>
</class>
<class name="eg.ClassALight" table="a" polymorphism="explicit">
...
<property name="BId" type="string">
<column name="b_id" sql-type="char(16)" not-null="false"/>
</property>
</class>
<class name="eg.ClassB" table="b" polymorphism="explicit">
...
<set name="ASet" table="a" cascade="none">
<key column="b_id"/>
<one-to-many class="eg.ClassALight"/>
</set>
</class>
<class name="eg.ClassBLight" table="b" polymorphism="explicit">
...
<set name="ASet" table="a" cascade="none">
<key column="b_id"/>
<one-to-many class="eg.ClassALight"/>
</set>
</class>
In the Java we are using session.evict() for all uploaded objects at the moment (because trying to be clear of this problem).
The problem comes up in the following scenario:
Code:
session = factory.openSession();
tx = session.beginTransaction();
list = session.find("Select a from eg.ClassALight");
for (Iterator iter = list.iterator();iter.hasNext();) {
ClassALight obj = (ClassALight) iter.next();
session.evict(obj);
}
tx.commit();
session.close()
session = factory.openSession();
tx = session.beginTransaction();
list = session.find("Select a from eg.ClassA where id = '1'");
for (Iterator iter = list.iterator();iter.hasNext();) {
ClassALight obj = (ClassALight) iter.next();
session.evict(obj);
}
tx.commit();
session.close();
Here we get:
net.sf.hibernate.WrongClassException: Object with id: 1 was not of the specified subclass: ClassALight (loaded object was of wrong class)
at net.sf.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:456)
at net.sf.hibernate.loader.Loader.getRow(Loader.java:423)
at net.sf.hibernate.loader.Loader.doQuery(Loader.java:209)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:133)
at net.sf.hibernate.loader.Loader.loadCollection(Loader.java:910)
at net.sf.hibernate.loader.Loader.loadCollection(Loader.java:885)
at net.sf.hibernate.loader.OneToManyLoader.initialize(OneToManyLoader.java:80)
at net.sf.hibernate.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:284)
at net.sf.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:3226)
at net.sf.hibernate.collection.PersistentCollection.forceInitialization(PersistentCollection.java:340)
at net.sf.hibernate.impl.SessionImpl.initializeNonLazyCollections(SessionImpl.java:3089)
at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:138)
at net.sf.hibernate.loader.Loader.doList(Loader.java:950)
at net.sf.hibernate.loader.Loader.list(Loader.java:941)
at net.sf.hibernate.hql.QueryTranslator.list(QueryTranslator.java:834)
at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1512)
at net.sf.hibernate.impl.QueryImpl.list(QueryImpl.java:39)
I think the problem could be that in the second query first Hibernate in the process of loading ClassA tries to load
associated class ClassBLight that has an association to ClassALight. Thus Hibernate has loaded ClassALight and when it then tries to build up
ClassA it already has ClassALight and don't upcast it to a ClassA. But it is "under the hibernate hood" from our applications point of view. And I dont see how we can evict that object.
We could change our objectmodel to work around this problem, but I am not really happy about doing that and thougt maybe I am doing some obvious error, being a novice using Hibernate.
Does anybody have any ideas or suggestions on this?
I would aprecciate it a lot.
/Guzman