Friday, March 8, 2013

Hibernate Course: Section: 9 - Advanced Mapping and Configuration v59 - v69

Compound Primary Key
it is always better to use surrogate keys (i.e ID field).
however sometimes we need a compound keys:

we have this example
Currency table has 3 columns (CurrencyName, CountryName, Symbol).
the key is CurrencyName & CountryName (e.g. Dollar,US or Dollar,Canada).

to represent that:


you can see, we use @Id for both fields, and we use IdClass(CurrencyId.class).

2- we define the IdClass

as you can see we defined the CurrencyId class, which implements serializable
THE FIELDS (name, countryName) MUST MATCH THE FIELDS NAME IN Currency class.

that is it, now if you want to use this key your wirte

as you can see, we use the CurrencyId object to get an object from database.

Compound Join Column
so now we have the Currency class, lets say we want to have a one to many relationship with this class.

how can we do the Join with a table where the table has 2 columns as a primary key
as you can see we use @JoinColumns and inside it set both columns

lets say you have this enum:

and you want to save this information in the table

Simply use @Enumerated

Mapped Superclass Inheritance 
lets say you have this data model
Stock (Stock_id, Name, Issuer, Purchase_date, Share_price, Quantity)
Bond (Bond _id, Name, Issuer, Purchase_date, Interest_Rate, Maturity_date)

so as you can see we have (Name, Issuer, Purchase_date) in both table, so we will abstract them and use inheritance when we define the entities:

this is the base class, notice the use of @MappedSuperclass

and here is the bond entity extending this class

IMPORTANT: when you are @MappedSuperClass, you dont have persistence life cycle, which means you cant have something like one to many relation with the Investment because it is not an entity, it is just heirachal thing

Table per class inheritance
to solve the issue in the previous example, we should not use @MappedSuperClass, we should use @Inheritance:

@Inheritance has 3 different mode, the first one is table per class, which means we should have a table for each class Bond, Stock and Investment ( the abstract class ).

we will not continue in the example the main idea is @Inheritance and the strategy is TABLE_PER_CLASS

in this TABLE_PER_CLASS, hibernate will do a UNION query to union the tables, this is a big drawback

Single Table Inheritance
in a single table inheritance, we will have only one table INVESTMENT, it has all the shared and unshared fields, we will distinguish between BOND and STOCK by adding what we call a discriminator field.

as you can see we defined the DiscrminatorColumn

now in Bond we do this

as you can see we removed the @Table annotation because Bond is not a table anymore

Building a Persistence Layer
it is better to have a package for Data.

start by a general DAO interface

Here you have the general operations that can be run on any table, find save delete

then implement this interface in AbstractDAO
basically you will implement all the methods in the DAO interface and we will add another methods that are generic for all interfaces

now we will have an DAO for each entity, so lets say user DAO

as you can see UserDAO extends DAO, so it will provide all the methods in DAO plus extra methods related to User, which is findByFirstName.

now we should implement this interface

as you can see we extednd the AbstractDAO to get all the general functionalities, and we implement the UserDAO functions.

so now if you have BANK, you create a BANK DAO interface then you implement it.

Views for COmplex Queries
sometimes you may have a complex query which you cannot do it in hibernate, in this case it is better to create a View in the database then you can simply map it in Hibernate:

Schema Generation
you can generate the tables based on the entities you defined, however this is something not for production, it is better just to do it for testing

as you can see, we should add this to the hibernate.cfg.xml

create means: create the tables
we have other options
validate: means check that the defined entities follow the tables structure we have in the database
update: if there is any new field for example it will be added
create-drop: means create the tables do everything then after we finish it will drop everything (which means when the program exits you will have a clean schema)

No comments:

Post a Comment