Monday, December 4, 2017

Hibernate



DEPENDENCIES

cglib|log4j|commons|SLF4J|dom4j|xalan|xerces

1.SESSION FACTORY

Reads configuration parameters
Connects to database 
Provides session objects


Approach 1


Approach 2


2.SESSION









Sample example


Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
//This is an example persiting data in database
  Stock stock = new Stock();

  stock.setStockCode("7052");
  stock.setStockName("PADINI");

  StockDetail stockDetail = new StockDetail();
  stockDetail.setCompName("PADINI Holding Malaysia");
  stockDetail.setCompDesc("one stop shopping");
  stockDetail.setRemark("vinci vinci");
  stockDetail.setListedDate(new Date());

  stock.setStockDetail(stockDetail);
  stockDetail.setStock(stock);


3.CRITERIA API

session.createCriteria(StockDailyRecord.class)
          .addOrder( Order.asc("date") );

  1. The commonly used methods of Criteria interface are as follows:
  2. public Criteria add(Criterion c) is used to add restrictions.
  3. public Criteria addOrder(Order o) specifies ordering.
  4. public Criteria setFirstResult(int firstResult) specifies the first number of record to be retreived.
  5. public Criteria setMaxResult(int totalResult) specifies the total number of records to be retreived.
  6. public List list() returns list containing object.
  7. public Criteria setProjection(Projection projection) specifies the projection.

Restrictions class

4.RESTRICTIONS API

_____________________________________________________________

Restrictions class provides methods that can be used as Criterion. The commonly used methods of Restrictions class are as follows:
  1. public static SimpleExpression lt(String propertyName,Object value) sets the less than constraint to the given property.
  2. public static SimpleExpression le(String propertyName,Object value) sets the less than or equal constraint to the given property.
  3. public static SimpleExpression gt(String propertyName,Object value) sets the greater than constraint to the given property.
  4. public static SimpleExpression ge(String propertyName,Object value) sets the greater than or equal than constraint to the given property.
  5. public static SimpleExpression ne(String propertyName,Object value) sets the not equal constraint to the given property.
  6. public static SimpleExpression eq(String propertyName,Object value) sets the equal constraint to the given property.
  7. public static Criterion between(String propertyName, Object low, Object high) sets the between constraint.
  8. public static SimpleExpression like(String propertyName, Object value) sets the like constraint to the given property.

Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
//This is an example persiting data in database
  Criteria criteria= session.createCrieria(abc.class);

  //ordering API
Getting records in ascending order

Criteria criteria 
= session.createCriteria(StockDailyRecord.class)
          .addOrder( Order.asc("date") );

Criteria criteria =
 session.createCriteria(StockDailyRecord.class)
        .addOrder( Order.desc("date") );

Criteria criteria = 
session.createCriteria(StockDailyRecord.class)
.add(Restrictions.eq/le/lt/gt/ge("volume", 10000));

Criteria criteria = 
session.createCriteria(StockDailyRecord.class)
       .add(Restrictions.like("stockName", "MKYONG%"));

Criteria criteria 
= session.createCriteria(StockDailyRecord.class)
         .add(Restrictions.between("date", startDate, endDate));
Criteria criteria 
= session.createCriteria(StockDailyRecord.class)
          .add(Restrictions.isNull("volume"));
Criteria criteria 
= session.createCriteria(StockDailyRecord.class)
         .add(Restrictions.isNotNull("volume"));



session.save(stock);
session.getTransaction().commit();



Fetching data of particular column

Criteria c=session.createCriteria(Emp.class);  
c.setProjection(Projections.property("name"));  
List list=c.list();  

Pagination with criteria API 

Criteria criteria = session.createCriteria(Foo.class);
criteria.setFirstResult(0);
criteria.setMaxResults(pageSize);
List firstPage = criteria.list();
Criteria criteriaCount = session.createCriteria(Foo.class);
criteriaCount.setProjection(Projections.rowCount());
Long count = (Long) criteriaCount.uniqueResult();
4.QUERY API








query.append(" order by date");    
Query result = session.createQuery(query.toString());   
  return result.list();

5.HQL

To get all records

Query query=session.createQuery("from Emp");

List list = query.list();

How will you setup pagination ?
Query query=session.createQuery("from Emp");   
query.setFirstResult(5);  
 query.setMaxResult(10);  
List fooList = fooList = query.list();
How will you count the last Page?
String countQ = "Select count (f.id) from Foo f";
Query countQuery = session.createQuery(countQ);
Long countResults = (Long) countQuery.uniqueResult();
Scroll pagination the last Page
String hql = "FROM Foo f order by f.name";
Query query = session.createQuery(hql);
int pageSize = 10;
ScrollableResults resultScroll = query.scroll(ScrollMode.FORWARD_ONLY);
resultScroll.first();
resultScroll.scroll(0);
List fooPage = Lists.newArrayList();
int i = 0;
while (pageSize > i++) {
    fooPage.add((Foo) resultScroll.get(0));
    if (!resultScroll.next())
        break;
}
https://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/Query.htm
https://docs.jboss.org/hibernate/orm/3.2/api/org/hibernate/Query.html
Update Query
Query q=session.createQuery("update User set name=:n where id=:i");   
q.setParameter("n","Udit Kumar");   q.setParameter("i",111);  
=session.createQuery("delete from Emp where id=100"); 
 //specifying class name (Emp) not tablename   
query.executeUpdate();
Aggregate functions
Query query
=session.createQuery("select sum(salary) from Emp");   
List list=q.list();   System.out.println(list.get(0));  
=session.createQuery("select sum(salary) from Emp"); 
session.createQuery("select max(salary) from Emp");  session.createQuery("select min(salary) from Emp");  
session.createQuery("select min(salary) from Emp");  
session.createQuery("select count(id) from Emp"); 
session.createQuery("select avg(salary) from Emp");   
               5.NAMED QUERIES
_________________________________________________________________________________________
In order to avoid code cluttering 
@NamedQueries(  
    {  
        @NamedQuery(  
        name = "findEmployeeByName",  
        query = "from Employee e where e.name = :name"  
        )  
    }  
//Hibernate Named Query 
Query query = session.getNamedQuery("findEmployeeByName");  
query.setString("name""amit");
  
6.Concept of Dirty Checking
______________________________________________________________________________________________ 
7.CACHING IN HIBERNATE
Hibernate provides 3 types of caching.
Hibernate Cache Types
  1. Session cache caches object within the current session.
      use load instead of query
  1. Query cache is responsible for caching queries and their results.
  2. Second level cache is responsible for caching objects across sessions.
Configuring session cache
____________________________________________________________________________________________________________________
 Session session = getSessionFactory().openSession();
 Transaction tx = session.beginTransaction();
 Query query = session.createQuery("from Person p where p.id=1");
 Iterator it = query.list().iterator();
 while (it.hasNext ()){
   Person p = (Person) it.next();
   System.out.println(p.getFirstName());
 }
 query = session.createQuery("from Person p where p.id=1");
 it = query.list().iterator();
 while (it.hasNext ()){
   Person p = (Person) it.next();
   System.out.println(p.getFirstName());
 }       
 tx.commit();
 session.close();
  Session session = getSessionFactory().openSession();
  Transaction tx = session.beginTransaction();
  Person person1 = (Person) session.load(Person.class, 1L);
  System.out.println(person1.getFirstName());
  Person person2 = (Person) session.load(Person.class, 1L);   
  System.out.println(person2.getFirstName());       
  tx.commit();
  session.close();

Difference between get and load method

Here are few differences between get and load method in Hibernate.
1. Behavior when Object is not found in Session Cache
Apart from performance this is another difference between get and load which is worth remembering. get method of Hibernate Session class returns null if object is not found in cache as well as on database while load() method throws ObjectNotFoundException if object is not found on cache as well as on database but never return null.
2. Database hit
Get method always hit database while load() method may not always hit the database, depending upon which method is called.
3. Proxy
Get method never returns a proxy, it either returns null or fully initialized Object, while load() method may return proxy, which is the object with ID but without initializing other properties, which is lazily initialized. If you are just using returned object for creating relationship and only need Id then load() is the way to go.
4. Performance
By far most important difference between get and load in my opinion. get method will return a completely initialized object if  Object is not on the cache but exists on Database, which may involve multiple round-trips to database based upon object relational mappings while load() method of Hibernate can return a proxy which can be initialized on demand (lazy initialization) when a non identifier method is accessed. Due to above reason use of load method will result in slightly better performance, but there is a caveat that proxy object will throw ObjectNotFoundException later if corresponding row doesn’t exists in database, instead of failing immediately so not a fail fast behavior.
5. load method exists prior to get method which is added on user request.

Here is a nice diagram which effectively explains the real difference between get and load in Hibernate

Difference between get and load method in Hibernate
When to use Session get() and load() in Hibernate

So far we have discussed how get and load are different to each other and how they can affect performance of your web application, after having this information in our kitty we can see some best practices to get most of load and get together. This section suggest some scenario which help you when to use get and load in Hibernate.
1. Use get method to determine if an instance exists or not because it can return null if instance doesn’t exists in cache and database and use load method to retrieve instance only if you think that instance should exists and non availability is an error condition.
2.  As stated in difference number 2 between get and load in Hibernate. get() method could suffer performance penalty if only identifier method like getId()  is accessed. So consider using load method  if  your code doesn't access any method other than identifier or you are OK with lazy initialization of object, if persistent object is not in Session Cache because load() can return proxy.
How to call get records in Hibernate using get and load method
If you look at below code , there is not much difference on calling get() and load() method, though both are overloaded now and can accept few more parameters but the primary methods looks exactly identical. It’s there behavior which makes them different.
//Example of calling get method of Hiberante Session class
Session session = SessionFactory.getCurrentSession();

Employee Employee = (Employee) session.get(Employee.class, EmployeeID);


//Example of calling load method of Hiberante Session

Session session = SessionFactory.getCurrentSession();

Employee Employee = (Employee) session.load(Employee.class, EmployeeID);
That’s all on difference between get and load in Hibernate. No doubt Hibernate is a great tool for Object relational mapping but knowing this subtle differences can greatly help to improver performance of your J2EE application, apart from practical reason get vs load method is also frequently asked questions in Hibernate interview, so familiarity with differences between load and get certainly helps.
http://javarevisited.blogspot.in/2012/07/hibernate-get-and-load-difference-interview-question.html


QUERY CACHE 
Defines the contract for caches capable of storing query results. These caches should only concern themselves with storing the matching result ids. The transactional semantics are necessarily less strict than the semantics of an item cache.
References:
https://www.dynatrace.com/news/blog/understanding-caching-in-hibernate-part-one-the-session-cache/
https://www.dynatrace.com/news/blog/understanding-caching-in-hibernate-part-two-the-query-cache/

Configuring query cache
____________________________________________________________________________________________________________________
The query cache is responsible for caching the results of queries – or to be more precise the keys of the objects returned by queries. 
hibernate.cache.use_query_cache
Session session = getSessionFactory().openSession();
 Transaction tx = session.beginTransaction();
 Query query = session.createQuery("from Person p where p.id=1");
 query.setCacheable(true);
 Iterator it = query.list().iterator();
 while (it.hasNext ()){
    Person p = (Person) it.next();
    System.out.println(p.getFirstName());
 }
 query = session.createQuery("from Person p where p.id=1");
 query.setCacheable(true);
 it = query.list().iterator();
 while (it.hasNext ()){
    Person p = (Person) it.next();
    System.out.println(p.getFirstName());
 }
 tx.commit();
 session.close();
Configuring secondary level cache
________________________________________________________________________________________________________________
Hibernate Caching :
----------------------------------------------------------------------
Hibernate second level cache uses a common cache for all the session object of a session factory. It is useful if you have multiple session objects from a session factory
Configuring EHCache
________________________________________________________________________________

1) Add 2 configuration setting in hibernate.cfg.xml file
cache.provider_class"
org.hibernate.cache.EhCacheProvider

"hibernate.cache.use_second_level_cache
true

2)Configuring cache strategy in entity .


@Entity
@Table(name = "employee", schema="spring_data_jpa_example")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
or
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT-READ-WRITE)
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
or
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)
________________________________________________________________________________
public class Employee implements Serializable { @Id @Column(name = "id") @GeneratedValue(strategy = GenerationType.SEQUENCE) private Long id; @Column(name = "firstname") private String firstName; @Column(name = "lastname") private String lastname;
________________________________________________________________________________

8.Inheritance Strategies

________________________________________________________________________________
















There are three types of inheritance mapping in hibernate 
1. Table per concrete class with unions 
2. Table per class hierarchy(Single Table Strategy
3. Table per subclass


@Inheritance(strategy = InheritanceType.SINGLE_TABLE)Discrimnator column 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)  
@Inheritance(strategy=InheritanceType.JOINED)  


Table per  class with unions

@DiscriminatorValue("")

@Entity
@Table(name = "Employee")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name = "VEHICLE_TYPE"
discrimnatorType = discrimnatorType.String
)
----------------------------------------------------------
@DiscrimnatornValue("Car")
-----------------------------------------------------------

Table per concrete class hierarchy

TPC@AttributeOverides
In case of Table Per Concrete class, tables are created per class. So there are no nullable values in the table. Disadvantage of this approach is that duplicate columns are created in the subclass tables.




















@Entity  
@Table(name = "employee102")  
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)  
  
public class Employee { 
________________________________________________________________
@Entity  
@Table(name="regularemployee102")  
@AttributeOverrides({  
    @AttributeOverride(name="id", column=@Column(name="id")),  
    @AttributeOverride(name="name", column=@Column(name="name"))  
})  
public class Regular_Employee extends Employee{ 

@Entity  
@Table(name="contractemployee102")  
@AttributeOverrides({  
    @AttributeOverride(name="id", column=@Column(name="id")),  
    @AttributeOverride(name="name", column=@Column(name="name"))  
})  
public class Contract_Employee extends Employee{  
________________________________________________________________


Table per sub class hierarchy




n case of table per subclass strategy, tables are created as per persistent classes but they are reated using primary and foreign key. So there will not be duplicate columns in the relation.

________________________________________________________________


@Entity  
@Table(name = "employee103")  
@Inheritance(strategy=InheritanceType.JOINED)  
 public class Employee {  


@Entity  
@Table(name="regularemployee103")  
@PrimaryKeyJoinColumn(name="ID")  
public class Regular_Employee extends Employee{  


@Entity  
@Table(name="contractemployee103")  
@PrimaryKeyJoinColumn(name="ID")  
public class Contract_Employee extends Employee{  


______________________________________________________________





HIBERNATE ANNOTATIONS


______________________________________________________________



@Entity
@Table(name = "EMPLOYEE")
public class Employee {
   @Id @GeneratedValue
   @Column(name = "id")
   private int id;

   @Column(name = "first_name")
   private String firstName;

   @Column(name = "last_name")
   private String lastName;

   @Column(name = "salary")
   private int salary;  


Following section will explain the annotations used in the above class.
@Entity
@Table(name = "ADDRESS",catalogue="",schema="",unique="")

@Id and @GeneratedValue Annotations

Each entity bean will have a primary key, which you annotate on the class with the @Id annotation. The primary key can be a single field or a combination of multiple fields depending on your table structure.
By default, the @Id annotation will automatically determine the most appropriate primary key generation strategy to be used but you can override this by applying the @GeneratedValue annotation, which takes two parameters strategy and generator that I'm not going to discuss here, so let us use only the default key generation strategy. Letting Hibernate determine which generator type to use makes your code portable between different databases.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
]@Column(name = "emp_id")
private long id;
@Id
@Column(name = "emp_id", unique = true, nullable = false)
@GeneratedValue(generator = "gen")
@GenericGenerator(name = "gen", strategy = "foreign", 
 parameters = { @Parameter(name = "property", value = "employee") })
 private long id;










JPA Annotations – Hibernate Annotations


Java annotation is a form of metadata that can be added to Java source code. Java annotations can be read from source files. It can also be embedded in and read from class files generated by the compiler. This allows annotations to be retained by JVM at run-time.
JPA annotations are not part of standard JDK, so you will get it when you add any implementation framework. For example, below hibernate maven dependency will get you JPA annotations too
org.hibernate.javax.persistence hibernate-jpa-2.1-api 1.0.0.Final

JPA Annotations for mapping java object to database table

Let us look at some of the important JPA annotations. Note that these annotations are present in javax.persistence package.
  1. javax.persistence.Entity: Specifies that the class is an entity. This annotation can be applied on Class, Interface of Enums.
  2. @Table: It specifies the table in the database with which this entity is mapped. In the example below the data will be stores in the “employee” table. Name attribute of @Table annotation is used to specify the table name.
  3. @Column: Specify the column mapping using @Column annotation. Name attribute of this annotation is used for specifying the table’s column name.
  4. @Id: This annotation specifies the primary key of the entity.
  5. @GeneratedValue: This annotation specifies the generation strategies for the values of primary keys.
  6. @Version: We can control versioning or concurrency using this annotation.
  7. @OrderBy: Sort your data using @OrderBy annotation. In example below, it will sort all employees_address by their id in ascending order.
  8. @Transient: Every non static and non-transient property of an entity is considered persistent, unless you annotate it as @Transient.
  9. @Lob: Large objects are declared with @Lob.
  10. import javax.persistence.*;
    
    @Entity
    @Table(name = "employee")
    public class Employee implements Serializable {
      
      @Id
      @Column(name = "id")
      @GeneratedValue(strategy=SEQUENCE, generator="ID_SEQ")
      private int id;
  11. @Version
      @Column(name = "version")
      private Date version;
    }
  12. @Transient
    Private int employeePhone;
  13. @OrderBy("id asc")
    private Set employee_address; 
  14. @Lob
    public String getEmployeeAddress() {
        return employeeAddress;
    }

Hibernate Annotations for Mapping between tables

  • Tables ’employee’ and ’employeeDetail’ have one-to-one association and they share the same primary key.
  • Tables ‘communication’ and ‘communicationDetail’ are linked by a foreign key. It is also a one to one association.
  • Tables ‘communication’ and ’employee’ are linked using a foreign key in many-to-one association with communication being the owner.
  • Tables ’employee’ and ’employeeStatus’ are linked through a foreign key in many-to-one association with employee being the owner.
@OneToOne
Employee and EmployeeDetail entities share the same primary key and we can associate them using @OneToOne and @PrimaryKeyJoinColumn.
In this case the id property of EmployeeDetail is not annotated with @GeneratedValue. The id value of Employee will be used for used for id of EmployeeDetail.
@Entity
@Table(name = "employee")
public class Employee implements Serializable {
   
  @Id
  @Column(name = "id")
  @GeneratedValue
  private int id;
   
  @OneToOne(cascade = CascadeType.MERGE)
  @PrimaryKeyJoinColumn
  private EmployeeDetail employeeDetail;
}
 
@Entity
@Table(name = "employeeDetail")
public class EmployeeDetail implements Serializable {
 
  @Id
  @Column(name = "id")
  private int id;
}
Points to note:
  • @PrimaryKeyJoinColumn should be used for associated entities sharing the same primary key.
  • @JoinColumn & @OneToOne should be mappedBy attribute when foreign key is held by one of the entities.
Communication and CommunicationDetail are linked through a foreign key, so @OneToOne and @JoinColumn annotations can be used. In snippet mentioned below, the id genereated for Communication will be mapped to ‘communication_id’ column of CommunicationDetail table. @MapsId is used for the same.
@Entity
@Table(name = "communicationDetail")
public class CommunicationDetail implements Serializable {
 
  @Id
  @Column(name = "id")
  @GeneratedValue
  private int id;
   
  @OneToOne
  @MapsId
  @JoinColumn(name = "communicationId")
  private Communication communication;
}
 
@Entity
@Table(name = "communication")
public class Communication implements Serializable {
 
  @Id
  @Column(name = "ID")
  @GeneratedValue
  private Integer id;
 
  @OneToOne(mappedBy = "communication", cascade = CascadeType.ALL)
  private CommunicationDetail communicationDetail;
}

@ManyToOne
Many employees can share the same status. So, employee to employeeStatus is a many to one relation. @ManyToOne annotation can be used for the same.
@Entity
@Table(name = "employee")
public class Employee implements Serializable {
 
  @ManyToOne
  @JoinColumn(name = "statusId")
  private EmployeeStatus status;
}

@OneToMany
Employee to Communication will be a one-to-many relationship. The owner of this relationship is Communication so, we will use ‘mappedBy’ attribute in Employee to make it bi-directional relationship.
@Entity
@Table(name = "employee")
public class Employee implements Serializable {
 
  @OneToMany(mappedBy = "employee", fetch = FetchType.EAGER)
  @OrderBy("firstName asc")
  private Set communications;
}
@PrimaryKeyJoinColumn
This annotation is used to associate entities sharing the same primary key.
@Entity
@Table(name = "employee")
public class Employee implements Serializable {
   
  @Id
  @Column(name = "id")
  @GeneratedValue
  private int id;
   
  @OneToOne(cascade = CascadeType.MERGE)
  @PrimaryKeyJoinColumn
  private EmployeeDetail employeeDetail;
}
@JoinColumn
@JoinColumn annotation is used for one-to-one or many-to-one associations when foreign key is held by one of the entities.
@ManyToOne
@JoinColumn(name = "statusId")
private EmployeeStatus status;
@JoinTable: @JoinTable and mappedBy should be used for entities linked through an association table.
@MapsId: Two entities with shared key can be persisted using @MapsId annotation.
@OneToOne
@MapsId
@JoinColumn(name = "communicationId")
private Communication communication;


CascadeType.PERSIST
CascadeType.DELETE
CascadeType.MERGE
CascadeType.REFRESH

  • ALL - all possible cascading operations performed on the source entity are cascaded to the target of the association.
  • MERGE - if the source entity is merged, the merge is cascaded to the target of the association.
  • PERSIST - if the source entity is persisted, the persist is cascaded to the target of the association.
  • REFRESH - if the source entity is refreshed, the refresh is cascaded to the target of the association.
  • REMOVE - if the source entity is removed, the target of the association is also removed.
I myself see them this way (more readable):
  • PERSIST is create new records from object in the database.
  • DELETE is, well, delete.
  • MERGE, for existing objects, to merge the existing data in the table with the data in my object. (sync to database)
  • REFRESH is to refresh the data in the object. Perhaps there was a change on the database which needs to be synced. (sync from database)

Hibernate Annotations for inheritance mapping

Now let us try to understand the inheritance mapping annotation in Hibernate.
Hibernate supports the three basic inheritance mapping strategies:
  • table per class hierarchy
  • table per subclass
  • table per concrete class
we will consider example for each type.
  1. Table per class hierarchy – single table per Class Hierarchy Strategy.
    @Entity
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name="cartype", discriminatorType=DiscriminatorType.STRING )
     
    @DiscriminatorValue("Car")
    public class Car {  }
     
    @Entity
    @DiscriminatorValue("BMW")
    public class BMW extends Car {  }
    
  2. Table per class/subclass – joined subclass Strategy.
    @Entity
    @Inheritance(strategy=InheritanceType.JOINED)
    public class Ship implements Serializable {}
     
    @Entity
    @PrimaryKeyJoinColumn
    public class Titanic extends Ship {}
    
  3. Table per concrete class.
    @Entity
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    public class Aeroplane implements Serializable {}
    
  4. @DiscriminatorColumn: As the name suggests this column is the descriminator and this annotation specifies the discriminator column for the SINGLE_TABLE and JOINED Inheritance mapping strategies.
    @Entity
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name="cartype", discriminatorType=DiscriminatorType.STRING )
    
That’s all for JPA and Hibernate annotations.
https://vladmihalcea.com/a-beginners-guide-to-jpa-and-hibernate-cascade-types/



@Emedable


@Entity
@Table (name=USER_TABLE)
public class UserDetails 
{
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    @Column(name=USER_ID)
    private int    userId;
    
    @Column(name=USER_NAME) 
    private String userName;
    
  @Embedded //For value type object
    private Address address;
    
    @Column(name=USER_PHONE)
    private String phone;
    
    @Column(name=DOB)
    private Date dob;

@Embeddable //for value object it is not is entity object.
 Value object means does not have real meaning for self individually.
public class Address
{
    @Column(name=STREET_NAME)
    private String street;
    @Column(name=CITY_NAME)
    private String city;
    @Column(name=STATE_NAME)
    private String state;
    @Column(name=PIN_CODE)
    private String pincode;


Eager and Lazy Loading
The first thing that we should discuss here is what lazy loading and eager loading are:
  • Eager Loading is a design pattern in which data initialization occurs on the spot
  • Lazy Loading is a design pattern which is used to defer initialization of an object as long as it’s possible
Let’s see how this actually works with some examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Entity
@Table(name = "USER")
public class UserLazy implements Serializable {
    @Id
    @GeneratedValue
    @Column(name = "USER_ID")
    private Long userId;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    private Set orderDetail = new HashSet();
    // standard setters and getters
    // also override equals and hashcode
}

CGLib Proxies and Hibernate Lazy Fetching

LazyInitializationException. 
Good read on proxies:
http://blog.xebia.com/advanced-hibernate-proxy-pitfalls/


AnnotationConfigurationFactory
session

@notnull
@null
@min
@max
@onetoone
@onetomany(cascade all/merge)
@many to one
@join
@jointable
@join column
@inversejoincolumn

Table per concrete class

@attribute.type



Table per Heirarchy

@

Table per subclass

Inhertitance.Type @primarycolumn


@Id
@Generate.Type Auto/Seperator


hibernate.cfg

dialects
connection
sessionfactory
hbmTOddl






HIBERNATE QUERY LANGUAGE
________________________________________________________________________________







-->






____________________________________________________________________








Hibernate Caching :



@Entity
@Table(name = "employee", schema="spring_data_jpa_example")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Employee implements Serializable {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    @Column(name = "firstname")
    private String firstName;

    @Column(name = "lastname")
    private String lastname;


ONE TO ONE - BIDIRECTIONAL 


@Entity
@Table(name="EMPLOYEES")
public class Employee implements Serializable {

    @OneToOne(fetch = FetchType.EAGER, mappedBy = "employee", cascade = CascadeType.ALL)
    private EmpDetails empDetails;



@Entity

@Table(name="EMP_DETAILS")
public class EmpDetails {

    @OneToOne
    @JoinColumn(name="EMP_ID")
    private Employee employee;

ONE TO MANY - UNIDIRECTIONAL 


@Entity
@Table(name="EMPLOYEES")
public class Employee implements Serializable {

    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @JoinColumn(name="EMP_ID")
    private List assetMgnt;




ONE TO MANY - BIDIRECTIONAL 


@Entity
@Table(name="EMPLOYEES")
public class Employee implements Serializable {

    @OneToMany(fetch = FetchType.EAGER, mappedBy="employee", cascade = CascadeType.ALL)
    private List assetMgnt;
______________________________________________________________________

@Entity
@Table(name="ASSET_MNGT")
public class AssetMgnt implements Serializable{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="AM_ID", unique = true, nullable = false)
    private Long amId;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="EMP_ID")
    private Employee employee;
______________________________________________________________________

MANY TO MANY  

@Entity
@Table(name="EMPLOYEES")
public class Employee implements Serializable {
    @ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinTable(
        name = "EMP_ASSIGNMENTS",
        joinColumns = { @JoinColumn(name = "EMP_ID") },
        inverseJoinColumns = { @JoinColumn(name = "PR_ID") }
    )
    private List empAssignmentList;      
____________________________________________________________________

    
@ManyToMany(mappedBy = "empAssignmentList")
    private List employees;
___________________________________________________________________

Embed & Embedable 

Two kind of objects in HIbernat e

value object  & entity object 


Embed & Embedable : used with embeddable objects





















________________________________________________________________


ONE TO ONE - UNI DIRECTIONAL  ONE TO ONE - BI DIRECTIONAL  ONE TO  MANY -UNI DIRECTIONAL 
CREATE TABLE EMPLOYEES (

    EMP_ID BIGINT NOT NULL AUTO_INCREMENT,
    NAME VARCHAR(252),
    DEPARTMENT VARCHAR(128),
    SALARY BIGINT,
    JOINED_ON TIMESTAMP,
    PRIMARY KEY (EMP_ID)
);

CREATE TABLE EMP_DETAILS (

    ED_ID BIGINT NOT NULL AUTO_INCREMENT,
    EMP_ID BIGINT,
    ADDRESS VARCHAR(252),
    GENDER VARCHAR(8),
    YEARS_OF_SERVICE BIGINT,
    BANK_ACCOUNT VARCHAR(128),
    PRIMARY KEY (ED_ID),
    FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEES(EMP_ID)
);

CREATE TABLE EMPLOYEES (

    EMP_ID BIGINT NOT NULL AUTO_INCREMENT,
    NAME VARCHAR(252),
    DEPARTMENT VARCHAR(128),
    SALARY BIGINT,
    JOINED_ON TIMESTAMP,
    PRIMARY KEY (EMP_ID)
);

CREATE TABLE EMP_DETAILS (

    ED_ID BIGINT NOT NULL AUTO_INCREMENT,
    EMP_ID BIGINT,
    ADDRESS VARCHAR(252),
    GENDER VARCHAR(8),
    YEARS_OF_SERVICE BIGINT,
    BANK_ACCOUNT VARCHAR(128),
    PRIMARY KEY (ED_ID),
    FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEES(EMP_ID)
);
CREATE TABLE EMPLOYEES (

    EMP_ID BIGINT NOT NULL AUTO_INCREMENT,
    NAME VARCHAR(252),
    DEPARTMENT VARCHAR(128),
    SALARY BIGINT,
    JOINED_ON TIMESTAMP,
    PRIMARY KEY (EMP_ID)
);

CREATE TABLE ASSET_MNGT (

    AM_ID BIGINT NOT NULL AUTO_INCREMENT,
    EMP_ID BIGINT,
    ASSET_NAME VARCHAR(128),
    VENDOR VARCHAR(128),
    PRIMARY KEY (AM_ID),
    FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEES(EMP_ID)
);

ONE TO  MANY -BI DIRECTIONAL  MANY TO  MANY -BI DIRECTIONAL 
CREATE TABLE EMPLOYEES (

    EMP_ID BIGINT NOT NULL AUTO_INCREMENT,
    NAME VARCHAR(252),
    DEPARTMENT VARCHAR(128),
    SALARY BIGINT,
    JOINED_ON TIMESTAMP,
    PRIMARY KEY (EMP_ID)
);

CREATE TABLE ASSET_MNGT (

    AM_ID BIGINT NOT NULL AUTO_INCREMENT,
    EMP_ID BIGINT,
    ASSET_NAME VARCHAR(128),
    VENDOR VARCHAR(128),
    PRIMARY KEY (AM_ID),
    FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEES(EMP_ID)
);
CREATE TABLE EMPLOYEES (

    EMP_ID BIGINT NOT NULL AUTO_INCREMENT,
    NAME VARCHAR(252),
    DEPARTMENT VARCHAR(128),
    SALARY BIGINT,
    JOINED_ON TIMESTAMP,
    PRIMARY KEY (EMP_ID)
);

CREATE TABLE PROJECTS (

    PR_ID BIGINT NOT NULL AUTO_INCREMENT,
    NAME VARCHAR(252),
    OWNER VARCHAR(252),
    PRIMARY KEY (PR_ID)
);

CREATE TABLE EMP_ASSIGNMENTS (

    EA_ID BIGINT NOT NULL AUTO_INCREMENT,
    EMP_ID BIGINT,
    PR_ID BIGINT,
    PRIMARY KEY (EA_ID),
    FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEES(EMP_ID),
    FOREIGN KEY (PR_ID) REFERENCES PROJECTS(PR_ID)
);


No comments:

Post a Comment