Hibernate Associations

August 14, 2018 | Author: piroaryan | Category: Software Design, Information Technology Management, Data Model, Data, Scientific Modeling
Share Embed Donate


Short Description

Download Hibernate Associations...

Description

Chapter 7. Association Mappings

Prev

 Next

Chapter 7. Association Mappings 7.1. Introduction Association mappings are the often most difficult thing to get right. In this section we'll go through the canonical cases one by one, starting with unidirectional mappings, and then considering the bidirectional cases. We'll We'll use Person and Address in all the examples. We'll classify associations by whether or not they map to an intervening join table, and by multiplicity.  Nullable foreign keys are not considered good practice in traditional data modelling, so all our examples use not null foreign keys. This is not a requirement of Hibernate, and the mappings will all work if you drop the nullability constraints.

7.2. Unidirectional associations 7.2.1. many to one A unidirectional many-to-one association is the most common kind of unidirectional association. create table Person ( personId bigint not null primary key, addressId bigint not null ) create table Address ( addressId bigint not null primary key )

7.2.2. one to one

A unidirectional one-to-one association on a foreign key is almost identical. The only difference is the column unique constraint. create table Person ( personId bigint not null primary key, addressId bigint not null unique ) create table Address ( addressId bigint not null primary key )

A unidirectional one-to-one association on a primary key usually uses a special id generator. (Notice that we've reversed the direction of the association in this example.) person create table Person ( personId bigint not null primary key ) create table Address ( personId bigint not null primary key )

7.2.3. one to many A unidirectional one-to-many association on a foreign key is a very unusual case, and is not really recommended.

create table Person ( personId bigint not null primary key ) create table Address ( addressId bigint not null primary key, personId bigint not null )

We think it's better to use a join table for this kind of association.

7.3. Unidirectional associations with join tables 7.3.1. one to many A unidirectional one-to-many association on a join table is much preferred. Notice that  by specifying unique="true", we have changed ch anged the multiplicity from many-to-many to one-to-many. create table Person ( personId bigint not null primary key ) create table PersonAddress ( personId not null, addressId bigint not null primary key ) create table Address ( addressId bigint not null primary key )

7.3.2. many to one

A unidirectional many-to-one association on a join table is quite common when the association is optional. create table Person ( personId bigint not null primary key ) create table PersonAddress ( personId bigint not null primary key, addressId bigint not null ) create table Address ( addressId bigint not null primary key )

7.3.3. one to one A unidirectional one-to-one association on a join table is extremely unusual, but  possible. create table Person ( personId bigint not null primary key )

create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique ) create table Address ( addressId bigint not null primary key )

7.3.4. many to many Finally, Finally, we have h ave a unidirectional many-to-many association. association. create table Person ( personId bigint not null primary key ) create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) ) create table Address ( addressId bigint not null primary key )

7.4. Bidirectional associations 7.4.1. one to many / many to one A bidirectional many-to-one association is the most common kind of association. (This is the standard parent/child relationship.)

create table Person ( personId bigint not null primary key, addressId bigint not null ) create table Address ( addressId bigint not null primary key )

If you use a List (or other indexed collection) you need to set the key column of the foreign key to not null, and let Hibernate manage the association from the collections side to maintain the index of o f each element (making the other side virtually inverse by setting update="false" and insert="false"): ... ...

It is important that you define not-null="true" on the element of the collection mapping if the underlying foreign key ke y column is NOT NULL. Don't only declare notnull="true" on a possible nested element, but on the element.

7.4.2. one to one A bidirectional one-to-one association on a foreign key is quite common.

create table Person ( personId bigint not null primary key, addressId bigint not null unique ) create table Address ( addressId bigint not null primary key )

A bidirectional one-to-one association on a primary key uses the special id generator. person create table Person ( personId bigint not null primary key ) create table Address ( personId bigint not null primary key )

7.5. Bidirectional associations with join tables 7.5.1. one to many / many to one A bidirectional one-to-many association on a join table. table. Note that the inverse="true" can go on either end of the association, on the collection, or on the join.

create table Person ( personId bigint not null primary key ) create table PersonAddress ( personId bigint not null, addressId bigint not null primary key ) create table Address ( addressId bigint not null primary key )

7.5.2. one to one A bidirectional one-to-one association on a join table is extremely unusual, but possible. create table Person ( personId bigint not null primary key ) create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )

create table Address ( addressId bigint not null primary key )

7.5.3. many to many association. Finally, Finally, we have h ave a bidirectional many-to-many association. create table Person ( personId bigint not null primary key ) create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) ) create table Address ( addressId bigint not null primary key )

7.6. More complex association mappings More complex association joins are extremely rare. Hibernate makes it possible to handle more complex situations using SQL fragments embedded in the mapping document. For  example, if a table with historical h istorical account information data defines accountNumber, effectiveEndDate and effectiveStartDatecolumns, mapped as follows: case when effectiveEndDate is null then 1 else 0 end

Then we can map an association to the current instance current instance (the one with null effectiveEndDate) using: '1'

In a more complex example, imagine that the association between Employee and Organization is maintained in an Employment table full of historical employment data. Then an association to the employee's most recent employer recent employer (the one with the most recent startDate) might be mapped this way: wa y: select employeeId, orgId from Employments group by orgId having startDate = max(startDate)

You can get ge t quite creative with this functionality, functionality, but it is usually more practical to handle these kinds of cases using HQL or a criteria query. query.

Hibernate: Understanding Associations - Associations: What are They? (Page 3 of 4 ) To represent relationships between classes, associations are used. Before going into the details of how Hibernate perceives associations, an understanding of the working of  container managed associations is needed. Managed association means that, if a change is made to one end of the association, it will be reflected at the other end. For example, let's consider the Order table. If it has a one-to-many relationship with the Product table, the Order class will have a one-to-many association with the Product class. So when changes are made to the attributes participating in this association, they will be reflected at the other end automatically. The developer doesn’t have to mange the associations manually. manually.

How Hibernate implements the management of association is different from that of  Container Managed Relationships/Associations or CMR generally provided b y EJB CMP. CMP. In CMR the association is bidirectional, whereas Hibernate treats each association as different. The primary reason is that Hibernate builds its persistence based on Plain Old Java Object or POJO, and in Java associations are unidirectional. Thus Hibernate doesn’t implement CMR. So the associations are unidirectional. In essence it means if the onupdate-cascade attribute is set in the mapping for Order and not in Product, any an y operation on Product would not affect Order. Keeping these points in mind, let's move on to the different types of associations supported by Hibernate. Hibernate mainly supports two types of associations: 1. One-to-Many 2. Many-to-One To work with associations, the changes would wou ld be required in both the mapping as well as in the persistence class. The details are as follows: 1. One-to-Many: In this kind of association association one object of a class is is in a relationship with many objects of  another class. The class that is having the single instance contains a collection of  instances of the other class. To specify this association the mapping file would have to be modified. The added code would be:

The name attribute takes the name of the variable that is participating in the association. The column attribute is used to specify the table column that is participating in the association. The class attribute takes the class name to which this class is associated. In the Persistent class the following change would be there: class { //other variable declarations Set =new HashSet(); //constructors and getter/setter code follows : }

Then the constructor with the added ad ded parameter for Set must be given along a long with the getter  and setter for the Set. In the third section I will be discussing a real world example to illustrate this point.

2. Many-to-One: This is the opposite of the One-to-Many association. In this case, the class that is having a Many-to-One association contains the object of the class. For example, if class A has a Many-to-One association with class B, then each instance of B would have an instance of  A. And the identity of this instance can be the same for multiple objects of B. The change in the mapping would be:

The attributes are the same as the case of One-to-Many. One-to-Many. In the case of code it would be class { o=new //construtors and getter/setter code follows : }

The associations will be clearer when I discuss the real world usage of association in the next section.

Hibernate: Understanding Associations - Associations in the Real World (Page 4 of 4 ) Till now I was using only one table. Let's make things interesting by adding one more table. This table is the Product table. Each Order can have more than one Product. Hence the relationship between Order and Product is One-to-Many. The schema of the Product table is:

CREATE TABLE PRODUCT( ID VARCHAR NOT NULL PRIMARY KEY, NAME VARCHAR NOT NULL, PRICE DOUBLE NOT NULL, AMOUNT INTEGER NOT NULL, ORDER_ID VARCHAR NOT NULL)

The next step is to create the persistent class for the Product table. The persistent class is as follows: package com.someorg.persist; public class Product { private String id; private String name; private double price; private int amount; private Order order; public Product(String id, String name, double price, int amount, Order order) { this.order=order; //others not shown for brevity } public String getId() { return id; } public void setId(String string) { id = string; } // default constructor and other // getters/setters not shown for brevity // ... }

The next part is Product.hbm.xml, that is the mapping file:







That is all that is required for the Product table. Now we need to make some changes in the Order class. package com.someorg.persist; import java.util.Date; import java.util.HashSet; import java.util.Set; public class Order { private String id; private Date date; private double priceTotal;

private Set products =new HashSet(); // Automatically set the creation time of // this Order public Order() { this.date = new Date(); } public Order(String id, Date date, private double priceTotal, Set products){ this.products=products; //others are not shown for brevity } public String getId() { return id; }

public void setProducts(Set products) { this.products = products; } public Set getProducts () { return products; } public void setId(String string) { id = string; } // other getters/setters not shown for

// brevity // ... }

The next part is changing in the Order.hbm.xml, which is:





The next step is to test it. To test it I will be using the Criteria query. In a QBC the joins are done using the setFetchMode method of the Criteria class. The mode would be JOIN. Here is how it works: import java.util.List;

//other imports // use as // java test. FindOrderById name public class FindOrderById { public static void main(String[] args) throws Exception { // query to issue String query = "select order from Order " + "where order.id=:id"; // search for what? String name = args[0]; // init Configuration cfg = new Configuration() .addClass(Order.class); SessionFactory sf = cfg.buildSessionFactory(); // open session Session sess = sf.openSession(); // search and return

Criteria criteria = session.createCriteria(Order.class); criteria.add( Expression.eq("id", name) ) .setFetchMode(“products”,FetchMode.JOIN); List result = criteria.list(); if (list.size() == 0) { System.out.println("No Order having id " + name); System.exit(0); } Order o = (Order) list.get(0); sess.close(); System.out.println("Found Order: " + o);//this is just an example Here the o // //object can be traversed to achieve anything } }

That brings us to the end of this discussion. Though the complete picture is becoming clear, some edges are still hazy. hazy. These edges will be brought brough t into sharper focus in the forthcoming discussions. Till next time.

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF