Tuesday, March 5, 2013

Hibernate Course: Section: 6 - Entity Associations V32 - V40

lets take the follwoing example

as you can see we have one to many relationship between transaction and account.
Transaction has Account_ID as a foreign key.

we can have the following java classes to simulate this relationship

you see inside Transaction you define account (Each transaction has one Account).

here Account is the target for the transaction, the account is in the transaction, and the account is the foreign key so it is the target object and the  Transaction. is the source object

with the example above you can just reach one direction of the relation, which means you can know the account related to a Transaction, however you cannot know the Transactions that are associated with the account, to do that you need a biderictional relation

as you can see we defined a List of Transactions in the Account class.

Uni-directional One to One Association
lets have this example

the relation between CREDENTIAL and FINANCES_USER is one to one as we have a unique constraint on the USER_ID column in CREDENTIAL.

now to simulate this relation in JAVA.

1- add this to hibernate.cfg.xml

2- then you should define this in JAVA:

as you can see we have User object, which makes Credential the Source Object and User the Target Object.
OneToOne annotation with CascadeType.All means when we persist Credential we should persist User.
JoinColumn: which means the column that should be used to join the tables, sure this column is the foreign key column in Credential ( think about it like this, if you want to join 2 tables which column shold be in ON clause).
the name="USER_ID" is the name of the column in the Source Table (in this case it is the Credential) and as you can see the name is USER_ID which is similar to the name we have in the Target Table.
in case the names are not similar you should set
@JoinColumn(name="Column_NAME_IN_SOURCE_TABLE", referencedColumnName="COLUMN_NAME_IN_TARGET_TABLE").

you define the JOINCOLUMN in the class that has the foreign key

4- now example of using this relation:

Bidirectional One to One Association
now we will continue in the above example, we will define a relation now from User to Credential:

as you can see here we define Credential with mappedBy="user" where user is the instance variable name in the Credentail table
Private User user;

never define a JOIN COLUMN in the reverse relationtion 
never define cascade in the reverse relation (you will create a loop)
we call the entity that has the join column (i.e. has the foreign key) the "OWNING ENTITIY"
the entity that doesnt have the foreign key "THE NON OWNING ENTITY"

Uni Directional one to many
we have this relation

we have one to many between Account and Transaction, and we will build a relationship from account to transaction.

so each account could be associated with multiple transactions.

we said before that the join column should be in the owning entity, and the owning entity is the table with the foreign key constrain, which means we should put the JOINCOLUMN in TRANSACTION.

however in this case we have a uni directional one to many, we will not have an Account field in Transaction object, and we need a place to specify the JOINCOLUMN, that is why we put it in Account.

Very important here, if you try to add Account and Transaction, we didnt set an inverse relation, which means we are not assigning Account_id in Transaction, which is a foreign key, which should not be null. now if you try to insert a record you will get an exception that the Account_id is null.

in order to solve this issue you should either specify the other side of the relationship or you should write @JoinColumn(name="ACCOUNT_ID", nullable = false).

Bi directional One To Many
so the first thing we should know that we have @OneToMany, and @ManyToOne
how do you read that, from the relation between Account and Transaction you say
We have One Account Related to Many Transaction ==> in Account we have @OneToMany
and we say we have ManyTransaction To One Account ==> in Transaction we have @ManyToOne

the transaction will look like this

as you can see we have now the JoinColumn in the owning entity, we have to remove the Join Column from the target entity and set mapped by.

One to Many with Join Table.
lets say that we have a Budget table, each budget is related to multiple transactions and each transaction has one budget.
This is a one to many relationship between the transaction table and the budget table.
however, not all Transactions has Budget, which means you will find alot of records with null value for the Budget Id.
that is why in this case you build this one to many relationship using a JOIN TABLE

as you can see we have BUDGET_TRANSACTION as a join table, one to one relationship between Transaction and Budget_Transaction and one to many between Budget and Budget_Transaction.

this is simply a one to many relation with a join table.

you can build that by

you can see, we use the jointable and joincolumn and inversejoincolumns

Uni-Directional Many to Many

lets say we have this relation,

in a uni directional many to many, we write this

defining the Join table in Account means that Account is the owning entity, now to make a bi directional many to many you do this

Bi Directional Many to Many
just define ManyToMany with mapped by

No comments:

Post a Comment