Friday, February 6, 2015

Hibernate

SessionFactory:

S.F. is an interface. The main contract here is the creation of Session instances. Usually an application has a single SessionFactory instance and threads servicing client requests obtain Session instances from this factory.
The internal state of a SessionFactory is immutable. Once it is created this internal state is set. This internal state includes all of the metadata about Object/Relational Mapping.
Implementors must be threadsafe.

SessionFactory sessionFactory = configuration.buildSessionFactory();
Simple words: S.F. is threadSafe. from the factory we will get session objects.


Session: 

Session is an interface and is a main runtime interface between a Java application and Hibernate. This is the central API class abstracting the notion of a persistence service.

The lifecycle of a Session is bounded by the beginning and end of a logical transaction. (Long transactions might span several database transactions.)

The main function of the Session is to offer create, read and delete operations for instances of mapped entity classes. Instances may exist in one of three states:

transient: never persistent, not associated with any Session
persistent: associated with a unique Session
detached: previously persistent, not associated with any Session.

It is not intended that implementors be threadsafe. Instead each thread/transaction should obtain its own instance from a SessionFactory.

A typical transaction should use the following idiom:

 Session sess = factory.openSession();
 Transaction tx;
 try {
     tx = sess.beginTransaction();
     //do some work
     ...
     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     sess.close();

 }
Simple Words: Session is a single threaded and shot lived object.

Query & Criteria interfaces

Load vs get:
session.load()
load will through an exception when there is no record found and it will always return proxy object/fake object.
It will always return a proxy object with the given identity value, even the identity value is not exists in database. However, when you try to initialize a proxy by retrieve it’s properties from database, it will hit the database with select statement. If no row is found, a ObjectNotFoundException will throw.


 Stock stock = (Stock)session.get(Stock.class, new Integer(2));
get will return null when the objects was not available in data base. It always get the value from data base real value. select statement will be run in data base and get the actual value.

Simple Words :When we use load it just create proxy object, when we actually call an method's of that proxy object it will hit the data base, in case if that object not available in data base it will through ObjectNotFoundException.

Update() and Merge() :

update will be executed with in the same persistence, ex.
Session session = sessionFactory.getSession();
Employee employee = session.get(Employee.class,3);
session.close();
employee.setName("I am name");
Session session1 = sessionFactory.getSession();
session1.update(session);

//It will through an exception.. stating session was closed...etc. In this case we can use merge() method irrespective of state of session it will update.


Mege:

Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session.


Cascade and Inverse:

1. inverse: This is used to decide which side is the relationship owner to manage the relationship (insert or update of the foreign key column).

2. cascade: In cascade, after one operation (save, update and delete) is done, it decide whether it need to call other operations (save, update and delete) on another entities which has relationship with each other.


Conclusion: In short, the “inverse” is decide which side will update the foreign key, while “cascade” is decide what’s the follow by operation should execute. Both are look quite similar in relationship, but it’s totally two different things. Hibernate developers are worth to spend time to research on it, because misunderstand the concept or misuse it will bring serious performance or data integrity issue in your application.

Basic criteria example:

List employees = session.createCriteria(Employee.class)
        .add(Restrictions.like("name", "a%") )
        .add(Restrictions.like("address", "Boston"))
.addOrder(Order.asc("name") )

.list();
Mappings:

one-to-many-relationship-diagram

@Entity
@Table(name="EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue
    @Column(name="employee_id")
    private Long employeeId;
   
 @ManyToOne
    @JoinColumn(name="department_id",
                insertable=false, updatable=false,
                nullable=false)
    private Department department;

public class Department{

@OneToMany(cascade={CascadeType.ALL})
    @JoinColumn(name="department_id")
    @IndexColumn(name="idx")
    private Set<employee> employees;

first-level:

The first-level cache is the Session cache and is a mandatory cache through which all requests must pass. The Session object keeps an object under its own power before committing it to the database.
If you issue multiple updates to an object, Hibernate tries to delay doing the update as long as possible to reduce the number of update SQL statements issued. If you close the session, all the objects being cached are lost and either persisted or updated in the database.


second level cache:
Second level cache is an optional cache and first-level cache will always be consulted before any attempt is made to locate an object in the second-level cache. The second-level cache can be configured on a per-class and per-collection basis and mainly responsible for caching objects across sessions.


Any third-party cache can be used with Hibernate. An org.hibernate.cache.CacheProvider interface is provided, which must be implemented to provide Hibernate with a handle to the cache implementation.

Query-level cache:

Hibernate also implements a cache for query resultsets that integrates closely with the second-level cache.


This is an optional feature and requires two additional physical cache regions that hold the cached query results and the timestamps when a table was last updated. This is only useful for queries that are run frequently with the same parameters.


Dialect:
which SQL language should be use to perform data base operations.

Composit-key:

@Entity
public class Project {
    @EmbeddedId ProjectId id;
     :
}

@Embeddable
Class ProjectId {
    int departmentId;
    long projectId;
}

joins in sql:
EmployeeLocation
EmpIDEmpName
13Jason
8Alex
3Ram
17Babu
25Johnson
EmpIDEmpLoc
13San Jose
8Los Angeles
3Pune, India
17Chennai, India
39Bangalore, India


select * from employee left join location
on employee.empID = location.empID;
Employee.EmpIDEmployee.EmpNameLocation.EmpIDLocation.EmpLoc
13Jason13San Jose
8Alex8Los Angeles
3Ram3Pune, India
17Babu17Chennai, India
25JohnsonNULLNULL

select * from employee right join location
on employee.empID = location.empID;

Employee.EmpIDEmployee.EmpNameLocation.EmpIDLocation.EmpLoc
13Jason13San Jose
8Alex8Los Angeles
3Ram3Pune, India
17Babu17Chennai, India
NULLNULL39Bangalore, India

The difference is simple – in a left outer join, all of the rows from the “left” table will be displayed, regardless of whether there are any matching columns in the “right” table. In a right outer join, all of the rows from the “right” table will be displayed, regardless of whether there are any matching columns in the “left” table.




No comments: