I have a question that is more in the realm of design, th开发者_开发问答an implementation. I'm also happy for anyone to point out resources for the answer and I'll gladly, research for myself.
Highly simplified Java and SQL:
Say I have a business domain POJO called 'Picture' with three attributes.
class Picture
int idPicture
String fileName
long size
Say I have another business domain POJO called "Item" with 3 attributes
class Item
int idItem
String itemName
ArrayList<Picture> itemPictures
These would be a normal simple relationship. You could say that 'Picture' object, will never exist outside an 'Item' object. Assume a picture belongs only to a specific item, but that an item can have multiple pictures
Now - using good database design (3rd Normal Form), we know that we should put items and pictures in their own tables. Here is what I assume would be correct.
table Item
int idItem (primary key)
String itemName
table Picture
int idPicture (primary key)
varchar(45) fileName
long size
int idItem (foreign key)
Here is my question: If you are making Hibernate mapping files for these objects. In the data design, your Picture table needs a column to refer to the Item, so that a foreign key relation can be maintained. However,in your business domain objects - your Picture object does not hold a reference/attribute to the idItem of Item - and does not need to know it. A java Picture instance is always instantiated inside an Item instance. If you want to know the Item that the Picture belongs to you are already in the correct scope. Call myItem.getIdItem() and myItem.getItemPictures(),and you have the two pieces of information you need.
I know that Hibernate tools have a generator that can auto make your POJO's from looking at your database. My problem stems from the fact that I planned out the data design for this experiment/project first. Then when I went to make the domain java objects, I realized that good design dictated that the objects hold other objects in a nested way. This is obviously different from the way that a database schema is - where all objects(tables) are flat and hold no other complex types within them. What is a good way to reconcile this?
Would you:
(A) Make the hibernate mapping files so that Picture.hbm.xml has a mapping to the POJO parent's idItem Field (if it's even possible)
(B) Add an int attribute in the Picture class to refer to the idItem and set it at instantiation, thus simplifying the hbm.xml mapping file by having all table fields as local attributes in the class
(C) Fix the database design because it is wrong, dork.
I'd truly appreciate any feedback
It seems to me that you don't really need anything in Picture
to reference its Item
, as you said that you will always have the Item
when you have the Picture
.
But if it turns out that you really need this reference, then it's the case of setting up bidirectional one-to-many association.
See how this is done here:
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/collections.html
Example:
<class name="Item">
<id name="id" column="item_id"/>
....
<set name="pictures" inverse="true">
<key column="item_id"/>
<one-to-many class="Picture"/>
</set>
</class>
<class name="Picture">
<id name="id" column="picture_id"/>
....
<many-to-one name="item"
class="Item"
column="item_id"
not-null="true"/>
</class>
Your Picture table would need to be modified to hold a reference to the item table, then you can store multiple pictures of items.
As for the hibernate mapping, you can map a collection of dependent objects (pictures) in hbm file of main object (Item). It's called component mapping.
You can check out the hibernate guide:
http://docs.jboss.org/hibernate/core/3.3/reference/en/html/components.html#components-incollections
I'm not sure about the xml configuration behind this, but using annotations you can just do something like this (JPA 2.0):
@Embeddable
class Picture
int id
String filename
long size
class Item
int idItem
String itemName
@ElementCollection
@CollectionTable(name = "item_picture", joinColumns = @JoinColumn(name = "item_id"))
List<Picture> pictures
Are there other attributes of the association? Such as dates, statuses, etc? If so, I would model it as:
table Item
int idItem (primary key)
String itemName
table Picture
int idPicture (primary key)
varchar(45) fileName
long size
table ItemPictureAssociation
int idItem (foreign key)
int idPicture (foreign key)
int sequence (composite PK)
<other columns>
This way you can maintain a one-to-many relationship, keep the two objects own details separate, and maintain attributes of the relationship if need be.
精彩评论