This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I am developing application with Hibernate and I have some difrent objects where each of them has a property History. This property in each object is a Set of History objects. I would like to map this relation with hibernate and I was doing it like this:
This is how object History looks in DB:
historyId | thema | objectId
idDocument | textDocument
idPerson | firstName | lastName
then I would like to map this objects (History <-> Document and History <-> Person) with relation One-To-Many where relation is mapped by columns:
objectId <-> idDocument and objectId <-> idPerson
and this not work - because it is two foreign keys to one column (objectId) and there is my question - How I should do this relation? It is possible to make many foreign keys to one column?
the problem with your approach is that Hibernate (or every other OR Mapping Tool) can't know what kind of data is linked to your history entry, unless the column (or attribute) you've named "thema" does tell what kind of entry this is.
What's possible is to have a history base object, and derived objects DocumentHistory, PersonHistory, etc.
On the database side you can map this into one table, this is called "Table per class hierarchy", the value of the so called discriminator column (which maybe your attribute "thema"?) will define what kind of history object (DocumentHistory,PersonHistory,..) is stored in a rowin the database.
You can google for "Hibernate Inheritance" or "table per class hierarchy" or just have a look at this Hibernate Inheritance to check if this is what you're looking for.
Joined: Feb 12, 2009
By the way: if you would define your relations unidirectional (Person -> History, Document -> History, etc.) you might be able to deploy your current solution, but without a discriminator column you will run into problems, because id is unique for Person and for Document, but a Person and a Document may have the same id and therefore you will get both histories for each Object.
Joined: Dec 01, 2008
Thank you for reply,
Column thema is only for example (it is not conected with relation). I can't use there Inheritance (this is requirement of project) I can only use of implementing interfaces - is it a way to do this with interfaces?
I will not have problems with duplicated ID's because Hibernate has one sequence in my DB and enumerates unique ID's for all records in all tables so I could do it without descriminator column but it wasn't work. Is this work properly only with unidirectional relations??
Joined: Feb 12, 2009
Well, I'm more used to EJB3 and have never tried such a thing... But when retrieving the wrong values is not a problem maybe you can try this:
define your objectId column in your History object and declare your ManyToOne relations as readOnly...
I had to do this because I had a column which was mapped twice, too. But in my case one mapping was for the primary key (a composed PK consisting of the PK of the master table and a counter). Declaring the relation readOnly made it work in my case...
As I said I'm only used to EJB3, but I think you have to set two properties for this: update="false" and insert="false"