Tuesday, October 18, 2011

One to Many association using Join Table

Here in this example, the one to many association will be achieved by using a join table.

Mapping using Hibernate XML mapping:

Let us go to the package com.demo.oneToManyUsingJoinTable and execute the class OneToManyUsingJoinTableExecutor.java

Things to look into:

* The ORM classes Buyer.java and Property.java
* The xml mapping file oneToManyUsingJoinTable.hbm.xml

ORM:


public class Buyer {

private long id;

private String buyerName;

Set properties = new HashSet();

//getter and setter methods

}

public class Property {


private long id;

private String propertyName;

private String propertyValue; private Buyer buyer;

//getter and setter methods
}

* The Buyer class has a variable of type Collections
* Both the classes have a reference to each other and hence bidirectional.

XML:

<hibernate-mapping auto-import="false">
<class name="com.demo.oneToManyUsingJoinTable.Buyer" table="BUYER" lazy="false">
<id name="id" column="BUYER_ID">
<generator class="native" />
</id>
<property name="buyerName" column="BUYER_NAME" />
<set name="properties" table="PROPERTY_BUYER" cascade="save-update" lazy="false">
<key column="BUYER_ID" />
<many-to-many class="com.demo.oneToManyUsingJoinTable.Property"
column="PROPERTY_ID" unique="true" />
</set>
</class>
<class name="com.demo.oneToManyUsingJoinTable.Property" table="PROPERTY" lazy="false">
<id name="id" column="PROPERTY_ID">
<generator class="native" />
</id>
<property name="propertyName" column="PROPERTY_NAME" />
<property name="propertyValue" column="PROPERTY_VALUE" />
<join table="PROPERTY_BUYER" optional="true" inverse="true">
<key column="PROPERTY_ID" unique="true" not-null="true" />
<many-to-one name="buyer" column="BUYER_ID" />
</join>
</class>
</hibernate-mapping>

* <set> declares that it is holding the collection of objects and they are stored in a separate table PROPERTY_BUYER
* <key> represents the foreign key column of the collection table PROPERTY_BUYER
* Here, the tag <many-to-many> is used instead of the tag <one-to-many>. This is because, the one-to-many does not know anything about the join table and hence this is indirectly achieved by using the many-to-one along with the constraint unique="true". Now the association is still a one-to-many with the join table.
* The one side of the association takes care of inserting the objects into the database as cascade is defined on the one side of the association.
* On the other hand, the <join> declares the join table.
* option="true" represents that the data can not be inserted if the any of these mapping columns are null.
* inverse="true" represents that it many side of the association will not insert the data into database rather the non inverse side will do the job for it.
*<many-to-one> declares the many-to-one association.

Once the OneToManyUsingJoinTableExecutor.java is executed, verify the results in the eclipse console as well as in the HSQL DB manager by executing the simple select queries on the tables Buyer, Property and Property_Buyer as follows.




Mapping by Annotations:

Let us now go to the package annotation.com.demo.oneToManyUsingJoingTable and execute the class OneToManyJoinTableAnnotationExecutor.java

Things to look into:

* The annotated ORM classes Buyer.java and Property.java

@Entity
@Table(name="BUYER")
public class Buyer {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="BUYER_ID")
private long id;

@Column(name="BUYER_NAME")
private String buyerName;

@OneToMany(mappedBy="buyer",cascade=CascadeType.ALL,fetch=FetchType.EAGER)
Set properties = new HashSet();

//getter and setter methods
}


@Entity
@Table(name="PROPERTY")
public class Property {

@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="PROPERTY_ID")
private long id;

@Column(name="PROPERTY_NAME")
private String propertyName;

@Column(name="PROPERTY_VALUE")
private String propertyValue;

@ManyToOne(fetch=FetchType.EAGER)
@JoinTable(name="PROPERTY_BUYER",joinColumns=@JoinColumn(name="PROPERTY_ID"),inverseJoinColumns=@JoinColumn(name="BUYER_ID"))
private Buyer buyer;

//getter and setter methods
}

* @OneToMany represents the one-to-many association
* mappedBy="buyer" is the simple inverse declaration of an association, naming the property on the target entity side (i.e) on the Property side.
* @JoinTable refers the table where the collection values will be stored.
* @ManyToOne declares the many-to-one association.

Once the
OneToManyJoinTableAnnotationExecutor.java is executed verify the results as mentioned above.