-
Notifications
You must be signed in to change notification settings - Fork 0
Hibernate
Thomas Czogalik edited this page Apr 26, 2019
·
11 revisions
ORM (object-relational mapping) Tool
in data layer
implements JPA
maps object into relational databases and visa versa
- provides a set of Java API for accessing the relational databases from Java program
- APIs enables Java programs to execute SQL statements and interact with any SQL compliant database
- database independent
- is a programming technique for converting data between relational databases and object oriented programming languages
- Hides details of SQL queries from OO logic.
- No need to deal with the database implementation.
- Transaction management and automatic key generation.
- mapping Java classes to database tables using XML files
- Provides simple APIs for storing and retrieving Java objects directly to and from the database.
- If there is change in the database or in any table, then you need to change the XML file properties only.
- uses JDBC
- created only once during application initialization
- provides two keys components
- Database Connection − This is handled through one or more configuration files supported by Hibernate. These files are hibernate.properties and hibernate.cfg.xml.
- Class Mapping Setup − This component creates the connection between the Java classes and database tables.
- configures Hibernate
- reads hibernate configuration file
- creates Session objects
- thread safe
- one SessionFactory object per database
SessionFactory factory = new Configuration()
.configure("hibernate.cfg.xml")
.addAnnotatedClass(Student.class)
.buildSessionFactory();
- used to get a connection with a database
- wraps JDBS connection
- used to save/retrieve objects
Session session = factory.getCurrentSession();
- unique id for each row in a table
- cannot be null value
use javax.persistence package
- marks class as an entity bean
- must have a no-argument constructor (at least protected scope)
- details of table that will be used to persist entity in database
- 4 attributes
- name
- catalogue
- schema
- constraints
- primary key
- automatically determines the most appropriate primary key generation strategy
- override generation strategy by applying @GeneratedValue
- strategy (check database for what is supported)
- GenerationType.AUTO: Pick appropriate strategy
- GenerationType.IDENTITY: using database identity column (auto increment)
- GenerationType.SEQUENCE: using database sequence
- GenerationType.TABLE: using database table to ensure uniqueness
- generator
- strategy (check database for what is supported)
- specify details of the column to which a field or property will be mapped
- attributes
- name
- length: size of the column
- nullable
- unique: only unique values
Student student = new Student("Daffy", "Duck");
session.beginTransaction();
session.save(student);
session.getTransaction().commit();
Session session = factory.getCurrentSession();
session.beginTransaction();
//by id
Student student = session.get(Student.class, student.getId());
session.getTransaction().commit();
//one student
Student student = session.get(Student.class, student.getId());
student.setFirstName("Scooby");
//student is a persistent object, no need for calling a setter, getter or save method
session.getTransaction().commit();
//multiple students
session.createQuery("update Student set email='foo@gmail.com'").executeUpdate();
//one student
Student student = session.get(Student.class, student.getId());
session.delete(student);
session.getTransaction().commit();
//multiple students
session.createQuery("delete from Student where email='foo@gmail.com'").executeUpdate();
load a complete persistent object
List<Student> students = session
.createQuery("from Student")
.getResultList();
to assign aliases to the classes in HQL queries
...
.createQuery("FROM Employee AS E")
obtain few properties of objects instead of the complete object
...
.createQuery("SELECT E.firstName FROM Employee E")
narrow the specific object that are returned from storage
...
.createQuery("FROM Employee E WHERE E.id = 10")
- order the results by any property
- ascending (ASC) or descending (DESC)
...
.createQuery("FROM Employee E WHERE E.id > 10 ORDER BY E.salary DESC")
- group it based on a value of an attribute
- use the result to include an aggregate value
...
.createQuery("SELECT SUM(E.salary), E.firtName FROM Employee E GROUP BY E.firstName")
The average of a property's value
The number of times a property occurs in the results
The maximum value of the property values
The minimum value of the property values
The sum total of the property values
- validate data before persisting it to database
- JPA provides EntityListeners
- provide method with return type void and no arguments
- annotate it with @PrePersist and @PreUpdate
@PrePersist
@PreUpdate
public void validateAlcoholByVolume() {
if (alcoholByVolume == null) {
throw new IllegalArgumentException();
}
if (alcoholByVolume.precision() > 3) {
throw new IllegalArgumentException();
}
if (alcoholByVolume.scale() > 1) {
throw new IllegalArgumentException();
}
}
- persist any Java datatype
- implement AttributeConverter interface of JPA
- convertToDatabaseColumn: converts your datatype into a database datatype
- convertToEntityAttribute: converts a database datatype into your datatype
- annotate your fields with
@Convert(converter = MyAttributeConverter.class)
- multiple users try to update same object at same time and one will be overwritten
- if update also update version (increment)
- if version does not match don't update
- annotate version field with
@Version - if saved new entities can have null versions
- if updated entities can not have null versions
- use below annotation and
@JoinColumn(name = "${name.of.column}")to config the column - to propagate entity state changes from Parents to Child entities use
cascade = CascadeType.ALLor other - remove orphans (objects B is bound to A. A is removed. B still lives) by adding
orphanRemoval = trueto relationship annotation
- for each A max one B
- two A instances can not share the same B instance
-
@OneToOneannotation - A can have a null reference to B
- for each A max one B
- two A instances can share the same B instance
-
@ManyToOneannotation
- A can reference many instances of B
- Each B can only belong to one A
-
@OneToManyannotation
- A can reference many instances of B
- Each B can belong to many As
-
@ManyToManyannotation
-
FetchTypespecifies if relationship neads to be fetched -
EAGER: relationship will be loaded immediately -
LAZY: relationship will be loaded on first use - set using attribute
fetch - default values:
- @OneToOne and @ManyToOne: EAGER
- @OneToMany and @ManyToMany: LAZY
- Objects that are loaded lazy are initialized with a proxy object
- proxy object is a sub class of the lazy loaded objects
- proxy object has all fields uninitialized
- real object is loaded after first method call