views:

305

answers:

4

Hey guys,

I have a question that is more in the realm of design, than 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

+1  A: 

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>
Bruno Rothgiesser
Thank you very much, apologies for the late answer marking. I borrowed Gavin King's book from a friend and read through the chapters on collections which cleared this concept up very much.
M. McKenzie
A: 

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

Gala101
You can check out the hibernate guide: http://docs.jboss.org/hibernate/core/3.3/reference/en/html/components.html#components-incollections
Gala101
A: 

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
Andrey
This is highly interesting and simple! I only intended to use the Hibernate implementation and research it's annotation capabilities later - but now am interested in this. Thank you very much!
M. McKenzie
A: 

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.