aspose file tools*
The moose likes Object Relational Mapping and the fly likes @ManyToMany, @ManyToOne, Join Tables Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "@ManyToMany, @ManyToOne, Join Tables" Watch "@ManyToMany, @ManyToOne, Join Tables" New topic
Author

@ManyToMany, @ManyToOne, Join Tables

Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Alright, I'll see if I can break this shiznit down. I am using Hibernate 3.2.x with JPA and annotations. Having pretty good luck so far. Just running into mapping issues. I'm not going to speak in terms of tables, only objects. What I have, and don't laugh, is a Toon. A Toon is associated with a User, which I have working just fine. I also have a ToonClass which is a very simple object with an id and a name. A ToonClass would be Warrior, Paladin, Warlock, etc. Then I also have a ToonRace which would be Night Elf, Human, Orc, etc.

A Toon can have a single ToonClass and ToonRace. A ToonClass and ToonRace can have many Toons. So at this point, the mapping seems fair simple:

Toon - ManyToOne - ToonClass
Toon - ManyToOne - ToonRace

But I thought it better to have a join table to limit the id dependencies between the objects. This is where I am getting confused. I want to map it so that I can get a List of Toons with their associated ToonClass and ToonRace. I doubt if I'll ever need to access Toon from ToonClass or ToonRace so it seems unidirectional. Is this right so far?

So here is my Toon class so far:


And the ToonClass


I'm just really at a loss as to how to specify the mappings at this point to get what I want. Thanks for any tips.
[ February 06, 2007: Message edited by: Gregg Bolinger ]

GenRocket - Experts at Building Test Data
Edvins Reisons
Ranch Hand

Joined: Dec 11, 2006
Posts: 364
My preferred way of modeling this remarkable domain would be to use enums, rather than entities, for the ToonClass and ToonRace, like this (example from the Persistence specification):



The names of Human, Orc,... types are going to appear in the code anyway, because the application will need to specify their behavior.
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Thanks Edvin, but the system isn't going to be that complex. I don't care about behvior. This is not a game. This is a tool for a game. I thought about just using an enum but it is possible that new races and new classes will appear, and I don't want to dig into code everytime that happens.

Thanks.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

I have a few comments, but do you mind if I answer it tomorrow, it is late tonight and my wife just got home.

Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

OK some basic changes I made to your code to demonstrate some points, you do not have to use it as I wrote it, you can do which ever way you like and feel that is easier for you.


First, for your Id's. It is best-practice to always name those attributes at "id". Hibernate will automatically take the class name and concatenate it with the "id" attribute so it will look for a column called TOON_ID

Hibernate also takes the class name and looks for a table with the same name, so you don't have to have the @Table annotation, unless you want or have a table name that is different than the class name.

@Columns are really only needed if the name of the column is different than the name of the class attribute.

@JoinColumn is also only needed if the foreign key column name is not the attribute's name concatenated with "id"



And the ToonClass

The only comment I might have on this is that I would probably keep the name of the column for the "TOON_CLASS_NAME" to be just "NAME"


The big key besides the "id" attribute is that I only annotate if the smart defaults don't work, meaning annotate to the exception only. But that part is my preference.

Now, let me do another post where I actually answer the question that you actually asked us for.

Mark
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

OK, well in your data model, sorry for coming at that angle, but your toon table with have two foreign keys, one to TOON_CLASS and other to TOON_RACE.

So it is just mapped in your Toon object as @ManyToOne, exactly like you have for your mapping of Toon object to a User.

There is also a way to map this relationship where the ManyToOne is still through a join table, but that is more of an exotic mapping. I will post a third response with that mapping.



Mark
[ February 07, 2007: Message edited by: Mark Spritzler ]
Gregg Bolinger
GenRocket Founder
Ranch Hand

Joined: Jul 11, 2001
Posts: 15299
    
    6

Thanks Mark. But what if I preferred a join table? And would you have a suggestion as to what makes more sense? Thanks.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

OK, now the exotic mapping. Here it is in xml



Not positive that I can have two <many-to-one>s like that, if that doesn't work with both of them, then you can have a <join> twice, but I would give my example a try first because, it is important to have it as one, so that the join table which has three ids in it, can't have a record where there is two ids, the toon_id and either race or class, then later in Java adding a link to the other race or class that wasn't there before and updating the record in the join table.

but in Annotations, it looks like they have to be two seperate annotations, one for race and one for class, but would be interested in finding out if it works.



Just be patient, I was typing this one when you posted.

Mark
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17250
    
    6

My suggestion that unless you have to save extra information that is specific to the Toon to class and race relationship, then just use the simple ManyToOnes where the foreign key is in the Toon table.

But if you do have extra information that will be in the join table, well now you have Composite objects, that you will make a class for, and then the best for that is to map the Composite object to the join table and re map your relationships to the Composite object as simple OneToOnes and OneToMany/ManyToOnes

Mark
 
 
subject: @ManyToMany, @ManyToOne, Join Tables