Hibernate - Advance
Hibernate - Advance
September 5, 2016
1. Collection Mapping
5. Hibernate Cache
Image 1
Image 2
Image 3
Item POJO
Item POJO
java.util.Collection
Item POJO
Indexed Column
java.util.List
• An unordered collection for key value pair that does not permit duplicate key is called a Map.
• java.util.Map or java.util.SortedMap reference is used for a Map property mapping.
• java.util.HashMap or java.util.TreeMap is used to initialize the collection,
Item POJO
java.util.Map
• Collection strategies for the collection of object remains same as discussed earlier.
• You can have a collection of embeddable POJO in your container pojo.
• If you were a ORM developer, you will have to define a strategy of mapping between object association and entity
relationship.
• Hibernate, as well as JPA, defines so many techniques for association–relationship mapping.
If a bid is added to
?
Item Object
• Hibernate doesn’t manage persistent associations. If you want to manipulate an association, you must write exactly
the same code you would write without Hibernate. If an association is bidirectional, both sides of the relationship must
be considered.
• In the above code, we have added a bid to an item and item was set to the bid object. At runtime, there are two
different in-memory representations of the same foreign key value: the item property of Bid and an element of the
bids collection held by an Item.
• In persistence context, both (item and bid) objects have been changed. Any change in the persistence context is
propagated to the database.
• In persistence context, Bid object is added and item object is updated. From the point of view of database, it is a single
change.
• Hibernate doesn’t transparently detect the fact that the two changes refer to the same database column. Hibernate
find that 2 objects in persistence context has been updated.
• @ManyToOne annotation does not have mappedBy attribute. So for one to many relationship, you can stop the
change made at the item end to be propagated to the database.
• Don’t you think that every bid should not be persisted programmatically? If we add bids to a persisted item, bids
should be persisted automatically.
If Item is deleted,
All bids are deleted
• Hibernate delete all the bids by executing delete statements. Hibernate does not use database cascade functionality.
• Create a POJO class BookOrder that has a one to many relationship with
Book class. It stores other information like order date, price, order state
and set of books ordered.
• Implement this association relationship by Hibernate/JPA.
• Use cascading operation while persist.
• Try it with different fetching strategies.
• Create a POJO class BookOrder that has a one to many relationship with
Book class. It stores other information like order date, price, order state
and set of books ordered.
• Implement this association relationship by Hibernate/JPA using book
name as the map key.
Equivalent to mappedBy,
Updatable and insertable attributes
are false.
© 2016 SAPIENT GLOBAL MARKETS | CONFIDENTIAL 58
One to One Association Using Same
Primary Key
One User has one shipping address
• In our on line shopping application, a user can be mapped to a single shipping address. We can have bidirectional one
to one mapping between user and address.
• We will have a one to one relation if Address table primary key references User table primary key.
Foreign Key
Generator
@OneToOne @PrimaryKeyJoinColumn
© 2016 SAPIENT GLOBAL MARKETS | CONFIDENTIAL 61
Exercise
• Create a POJO class Book that has a one to one relationship with cover
image class.
• Implement this association relationship by Hibernate/JPA same primary
key approach.
mappedBy at
Address end
@OneToOne
© 2016 SAPIENT GLOBAL MARKETS | CONFIDENTIAL 65
Exercise
• Create a POJO class Book that has a one to one relationship with cover
image class.
• Implement this association relationship by Hibernate/JPA same unique
foreign key approach.
Order Column
• Create a POJO class Book that has a many to many relationship with
Book Categories. We can fetch books of one category but we can not
fetch categories of a book.
• Implement this association relationship by Hibernate/JPA.
• Create a POJO class Book that has a many to many relationship with
Book Categories. We can fetch books of one category and vice-versa.
• Implement this association relationship by Hibernate/JPA.
• If getReference() can’t find the object in the cache or database, an unchecked exception EntityNotFoundException is
thrown. The getReference() method never returns null. The find() method returns null if the object can’t be found.
• The getReference() method may return a proxy instead of a real persistent instance. A proxy is a placeholder that
triggers the loading of the real object when it’s accessed for the first time. On the other hand, find() never returns a
proxy. find() method either hit the database or take the object from cache.
• We have used getReference() method to have the reference of an item entity with item_id 1. When we execute above
program, no select query is executed. Hibernate generates a proxy of item object (Usually a subclass of Item
overriding access methods) at runtime.
• When you define a collection for lazily fetched, a proxy of collection is created at runtime. A collection is initialized if
you start iterating through its elements or if youhere
Entity is fetched call ifany of the iscollection-management
identifier operations,
Entity is fetched such as is
here if identifier size() and
contains(). field accessed not field accessed
Need
No to have
need to the
addreference of Item
bids to item.
Transaction is over.
• Do you agree that item object should be fetched from the database while only bid entity is to be persisted to the
database? Required item id for bid association has been given to the getReference() method.
• We should have only one insert statement:
• Hibernate lazily fetch address object for each item in a separate database call.
• Hibernate offers an optimization named: Batch Fetching or blind-guess-optimization.
• You are telling hibernate to pre-fetch up to 10 uninitialized proxies in a single SQL select, if a single proxy is initialized.
• The resulting query is looks like below:
Select a.* from AddressFKA a where a.id in (?,?,?)
How can Hibernate be configured to access an instance variable directly and not through a setter method
?
Is it possible to perform collection mapping with One-to-One and Many-to-One?
The L1 cache is connected directly to the Hibernate Session, ie the L1 cache runs throughout the lifecycle of
the Session object, thus "born" and "die" with him. Because the L1 cache is internal to a Session object, it
can not be accessed from other Sessions created by the Session Factory.
Note-
Fist level cache Is is enabled by default and works in session scope.
Second level cache is apart from first level cache which is available to be used globally in session factory
scope.
Different strategies-
• Read Only: This caching strategy should be used for
persistent objects that will always
read but never updated.
• Read Write: It’s good for persistent objects that can be
updated by the hibernate application.
• Nonrestricted Read Write: If the application only
occasionally needs to update data and strict transaction
isolation is not required, a nonstrict-read-write cache
might be appropriate.
• Transactional: The transactional cache strategy provides
support for fully transactional cache providers such as
JBoss TreeCache.
Suppose there is a requirement to have two columns - created_date and updated_date in Persontable.
created_date should be filled automatically whenever a new record is inserted into table.
updated_date should be updated automatically whenever the corresponding row is modified.
Note-
Coalesce (...) is similar to Oracle's nvl() function and supported by all major DBs.
It returns the first non-null argument.
Current_Timestamp is similar to Oracle's sysdate() function and supported by all major DBs.
@FilterDef: Defines filter definition name and parameters to set values while enabling filter.
@Filter: Adds filter to an entity or a target entity.
@Filters: To define more than one @Filter, use @Filters.
@FilterJoinTable: Use it to filter join table.
Session.enableFilter(): Finally filter is enabled using this method. We need to pass filter definition name.
Session.disableFilter(): Pass filter definition name to disable filter.
deduceAliasInjectionPoints: This is the attribute of @Filter annotation which has Boolean value that controls
explicit aliasing.
While using filter, we need to use session method as Session.enableFilter() passing filter definition name. It
returnsorg.hibernate.Filter instance. To set parameter values, filter provides setParameter() method. Finally if
we want to disable filter, we just use Session.disableFilter() passing filter definition name.
To filter collection load in hibernate association, we need to use @FilterJoinTable annotation. This annotation is
applied at association level within entity.
@FilterJoinTable is used with @JoinTable. When entity is loaded, collection will be filtered according to
@FilterJoinTable definition.
Output-
In Any relationship, the table holding the relationship would have two columns for relationship management.
One to identify the primary key value of record being associated and another to identify the table to which the
associated record belongs.
Result-
Optimistic locking assumes that multiple transactions can complete without affecting each other, and that
therefore transactions can proceed without locking the data resources that they affect. Before committing, each
transaction verifies that no other transaction has modified its data. If the check reveals conflicting modifications,
the committing transaction rolls back. Hibernate provides two different mechanisms for storing versioning
information, a dedicated version number or a timestamp.
Version number
Timestamp
Pessimistic locking assumes that concurrent transactions will conflict with each other, and requires resources
to be locked after they are read and only unlocked after the application has finished using the data.
JPA 2.1 brings a new feature named attribute converter, which can help you convert your custom class type to
JPA supported type.
In this example, we try to store the tags property into one column instead of an external table.
Create an attribute converter, it should be annotated with @Converter and
implementsAttributeConverter interface.
It is easy to understand, the tags property will be converted into a comma based string when it is stored into
database, and tags field value of Person table will be converted into a List when it is fetched from database.
You can use the autoApply attribute of the Converter to apply the converter to any supported type.
It is dangerous in a real world project when there are some List you do not want to be converted. Alternatively,
you can apply it on the property via a @Convert annotation.
An extra attributeName must be specified. You can declare several Converters for properties on an Entity class.
As an example, take a String attribute if there isno explicit type mapping, Hibernate looks to the
BasicTypeRegistry to find the registered mapping forjava.lang.String.
As a baseline within BasicTypeRegistry, Hibernate follows the recommended mappings of JDBC for Java types.
JDBC recommends mapping Strings to VARCHAR, which is the exact mapping that StringType handles. So
that is the baseline mapping within BasicTypeRegistry for Strings.
In these cases you must explicitly tell Hibernate the BasicType to use, via
theorg.hibernate.annotations.Type annotation.
• Create a website for BullishBears India which will manage the shares portfolio for their clients. The website would
have the following layout
• Login Page
The initial page that will open and it will have the following layout
The right hand pane for sell stock page would look like this –
The stock name would be a hyperlink and clicking on it would show the following Sell Stock Order page(in the same
pane).
The right hand pane for buy stock page would look like this –
Stock Name Buy Quantity Mkt Price Amount
ABC 45.4
FICT 78
FRAD 63
DICT 98
BUY Reset
When the client presses the BUY button after specifying the quantity. A backend validation would be required to
check if the client has enough money for the order to be processed.
• This page would show the user details – Initially (read only)
o Client name
o Contact details (address, contact number, email id)
o Account balance
• The user will be given an option to update his details, where he would be able to update his address, phone, email id
(not his name).
• This page would show the transaction history of the client, it will show in a tabular format the transactions he has
made (All of the transactions)