I was wondering if there is a way to do a Hibernate mapping for the following. My two days spent on this say no.
There are two tables related to one to many .
+---------------------+ +-----------------+ | versioned_entity | | basic_entity | +---------------------+ +-----------------+ | fk_BasicEntityId | * 1 | id | | version |-------| active_version | | ... | | ... | +---------------------+ +-----------------+
Sleep Mode Display:
<class name="my.VersionedEntity" table="versioned_entity"> <composite-id> <key-many-to-one name="basicEntity" column="fk_BasicEntityId"/> <key-property name="version"/> </composite-id> ... </class> <class name="my.BasicEntity" table="basic_entity"> <id name="id"> <property name="activeVersion" not-null="true"> <column name="active_version"/> </property> ... </class>
Short explanation: fk_BasicEntityId is a foreign key pointing to basic_entity.id . An entry in versioned_entity can be identified by its foreign key and version (there can be many versions with the same fk_BasicEntityId ). active_version is a number that points to one of the versioned_entity entries and tells which version is "active". Hope this is clear enough.
Now the problem I am solving is that I need quick access to Java:
my.BasicEntity basic = my.BasicEntityDAO.get(); my.VersionedEntity activeVersion = basic.getActiveVersionedEntity();
The current implementation is performed in Java and simply iterates over all versioned objects of this base object and checks if its version matches the active one. Needless to say, this does not scale and does not lead to performance problems.
So, I went to the database level. Does it look simple? So I thought! I continued and added the following to Hibernate-mapping basic_entity:
<many-to-one name="activeVersionedEntity" not-null="false" insert="false" update="false"> <column name="id" unique="true" not-null="true"/> <column name="activeVersion"/> </many-to-one>
This requires a double column for versioned_entity have a composite key. Unfortunately, this will not work - the JVM dies without a trace when the call to be.getActiveVersionedEntity() is called (on the colleague's computer, it throws a StackOverflowError inside Hibernate). I suspect this is happening because "id" is also an identifier, since I have a very similar mapping for the same class where the column is not an identifier, and this works correctly.
Maybe I could do it using HQL, but it would require me to move this method to the DAO class, which is especially inconvenient, since it will require changes to the API (not an option). Using the DAO call inside my.BasicEntity::getActiveVersionedEntity() is another big no-no: I can't mix different levels of abstraction. Another way to resolve this issue would be to search for Interceptors / events, but this is probably also one of those options that pursue the purpose of the structure (I don't need to take care of such low-level things like me?).
I am running Hibernate version: 3.2.7GA / Spring 2.5.6. The documentation is incredibly poor - I looked at three different Hibernate books, online documentation, forums, etc.
Any help is appreciated.