Showing posts with label Hibernate. Show all posts
Showing posts with label Hibernate. Show all posts

Tuesday, February 27, 2018

Hibernate Envers

Please follow Rest API Server to see the big picture and GitHub repo details.

Hibernate Envers helps in creating an audit trail of the records in the database. Hibernate Envers audits all the attribute changes in an audit table. To enable the support for Hibernate Envers, add the dependency

    compile('org.hibernate:hibernate-envers')

Add the appropriate version. If you are using Spring boot dependency management then the version will be automatically taken care by Spring boot.

Tuesday, February 13, 2018

Rest based API server

Photo credit: Pixabay.com
Rest based API servers are very common these days. This has also led to the logical separation of front-end and back-end. New front-end techniques like Single page applications nicely fit with these concepts and also is a logical separation of ownership. Backend deals with providing the information in the form of API and front-end deals with presenting them in an appropriate way. This is also true for mobile applications that connect to the backend via Rest-based API's.

Saturday, December 17, 2016

Creating EntityManagerFactory in Spring

To create JPA based EntityManagerFactory backed by Hibernate implementation in Spring which gets auto configured, follow the code

@Configuration
@EnableAutoConfiguration
//package containing the mapped model
@EnableJpaRepositories(basePackages = "com.lalit.example.Model")
@EnableTransactionManagement
public class DatabaseConfiguration {
        //You can autowire env which contains values from properties file or you
        //can inject properties directly using $
@Autowired
Environment env;

        //This will also create a pool of connections
@Bean
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(env.getProperty("db.driver"));
dataSource.setUrl(env.getProperty("db.url"));
dataSource.setUsername(env.getProperty("db.username"));
dataSource.setPassword(env.getProperty("db.password"));
dataSource.setPoolPreparedStatements(true);
dataSource.setMaxOpenPreparedStatements(20);
return dataSource;

}

@Bean(name="entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
// Put all the Hibernate properties
Properties additionalProperties = new Properties();
additionalProperties.put("hibernate.dialect", env.getProperty("hibernate.dialect"));
additionalProperties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
additionalProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));

LocalContainerEntityManagerFactoryBean entityManagerFactory = new LocalContainerEntityManagerFactoryBean();
entityManagerFactory.setDataSource(dataSource());

JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); entityManagerFactory.setJpaVendorAdapter(vendorAdapter);
entityManagerFactory.setJpaProperties(additionalProperties);

entityManagerFactory.setJpaProperties(additionalProperties);

return entityManagerFactory;
}

        //Hook the transaction manager
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}

        //Hook the exception translator
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}


}

Saturday, August 30, 2014

Spring Hibernate jQuery Tiles Web Application with Source Code

Spring and Hibernate are one of the most favourite frameworks to build web applications in real world. Spring not only provides a mature service layer but also gives good integration with Hibernate. Spring also provides MVC to build front end pieces and Spring security to take care of authentication and authorization. Apart from that on browser side jquery has proven itself with time. I have put together a sample web application, where one can see how the different frameworks are integrated. The web application has a login page and a listing page. 

The versions of different frameworks used are:

Saturday, August 2, 2014

ORM or JDBC

Data access is fundamental to web applications. All non trivial applications and rarely with an exception do have a database and hence a data access layer. SQL has emerged as the de-facto standard to access the database. SQL stands for Structured Query Language and is independent of any programming language. Whether it's .Net, Java, C++ SQL is the prominent way of talking to database. However we are here discussing about Java than let's look more closely on the way it is handled.
In Java the question basically boils down to a choice between JDBC or ORM (hibernate/entity beans). In ORM there are again couple of choices. The most preferred choice is Hibernate but with EJB3.0 (JPA and entity beans), the standard has also embraced the hibernate concepts. In fact

Tuesday, July 29, 2014

Hibernate Tool

Hibernate tool comes as an eclipse plugin. This has useful feature including HQL editor which helps in development. To install Hibernate Tool follow the steps :
  • In Eclipse: Go to Help->Install new software
  • Add the link at Work With: http://download.jboss.org/jbosstools/updates/development/luna/
  • Expand JBoss Application Development
  • Select Hibernate Tools
  • Click on Next and follow the instructions

Monday, July 28, 2014

Debugging Hibernate

Debugging Hibernate application tends to be tricky as there is a time lag between application issuing a calls on hibernate api and hibernate issuing SQL to the database.We will look into various strategies to look into how to debug hibernate.
Configuration
Enable show_sql property in the hibernate configuration file. In your hibernate.cfg,xml put the following
<!-- Log out all the sql that hibernate is issuing to datbase.
             This is very useful for debugging -->
        <property name="show_sql">true</property>

Sharding in Hibernate

Sharding is basically horizontal partitioning of data. If handled carefully, sharding can improve performance. For example let's say for a online mail provider, the mail subscribers can run into huge numbers. If all the rows of the database are sitting in the same server, it would hog a huge amount of memory. Sharding can help in horizontal partitioning of data. We can partition the records on the basic of continents. The continent information derived from the country information. So the rows belonging to North America and Asia would be sitting on different servers. If the queries are always continent specific most of the time, this partitioning will help in improving the performance and also indexing will be better. The care should be taken that if we have queries which involve going to different databases to fetch the result set, and if this is a prevalent scenario, sharding would result in degradation of performance.
Hibernate Shards helps in dealing with horizontal partitioning of data. To use shards, let's assume we have a EmailUser table where the user data is saved. We will save the records alternately in two

Second level Cache in Hibernate

Hibernate second level cache are important for performance perspective. A second level cache is a process specific cache and is shared by all the individual session running in different threads. The data points which are good candidates for caching are:
  • Data which never change, like list of countries, timezone,role types etc.
  • Data that rarely change. (A more changing data in cache will lead to Hibernate doing more work as it has to write to database and has to take care of objects in cache).
To enable the cahce first we need to enable some properties in configuration. I am showing an

Maintaining a Long Session in Hibernate

Sometimes we need to maintain a long running session. For example, we need to do some intermediate calculation and keep track of them. The user might at the end chose to discard it or retain it. For the same purpose, we might want to keep a long running session in the Hibernate. Another way is to keep a long running transaction, but many times the transaction times out because of the underlying database. Also be careful about the issues of entities being updated by other threads, which are more about versioning issues. This can lead to commit getting failed at the end, if versioning is enabled for the entities.
The way to handle this is usually to open a hibernate session at the start of workflow and then keep the hibernate session in the Http session object. Whenever next requests comes up, the hibernate

Hibernate Query Language - HQL

Session API's are used when an entity needs to be fetched from the database. To fetch list of records which might involve joins we have to use Hibernate Query Language (HQL). HQL queries are similar to SQL. They are written in OO way. Hibernate supports criteria queries also which are type safe way of writing queries. Hibernate supports the JPA QL also. Hibernate also supports issuing native SQL queries. The Query interface is used to build and execute queries.

Fetching List
To fetch a list
In HQL:

Hibernate Entities Life cycle

The entities managed by Hibernate has a life-cycle associated with them. Either you can make a new object in heap and save it into a database or the data can be fetched from the database and given to the user as an object. The hibernate objects go through certain stages in the life-cycle. Only entity objects participate in the life cycle. The value objects do not participate in the life-cycle. The stages in the life cycle of an entity managed by Hibernate are as follows:
Transient Objects
When objects are created in the Java layer with a new or similar operator and they have no corresponding record existing in database than these objects are termed as Transient objects. These

Hibernate Persistent Context and Session

The concept of Persistent Context and Session are central to the runtime behavior of Hibernate. Persistent Context is a run time memory area where Hibernate holds the references of objects and Session provides API to interact with the objects. Let's look them into one by one.
Persistent Context
At runtime whenever a session is opened and closed, between those open and close boundaries Hibernate maintains the object in a Persistence Context. Think of it like a first level runtime cache which hibernate controls. Hibernate does automatic dirty checking and transactional write-behind for the entity managed in Persistent Context. Hibernate guarantee a scope of Java object identity in this

Mapping Inheritance in Hibernate

Inheritance is an important concept in Java but there is no counterpart in Relational world. There are some solutions in relational world but they are not widely used and also vendor specific. Hibernate provide some strategies to handle this situation where the inheritance hierarchy is mapped into the relational world.

Let's have the java classes where we have a User class and Employee and Customer are inherited from it. The various strategies employed by hibernate to map this hierarchy to relational world is as follows:
  • Single Table per class hierarchy – Single table has all properties of every class in the hierarchy.
  • Table per concrete class – Each subclass has a table having all the properties of super class also.
  • Table per subclass – Each class is mapped in its own table. There is separate table for super class and subclass.Table
Single Table per class hierarchy
In Single table per subclass, the union of all the properties from the inheritance hierarchy is mapped

Relationship Mapping in Hibernate

Hibernate relationship mapping takes care of mapping the relationship in the relational world. The relationship that exist in the relational world are:
  • @OneToOne
  • @OneToMany
  • @ManyToOne
  • @ManyToMany
Though the notion of directionality is not present in relational world, it is relevant for the Java world. So we will have to handle in the Java world whether we want to build unidirectional or bidirectional relation. Please note the the need of unidirectional or bidirectional relationship should be governed by

Collection Mapping In Hibernate

Hibernate supports collection mapping as value type. In Hibernate collection mapping, the collection are mapped into a separate table but are not exposed as entity on the Java side. Hibernate supports following collection interfaces as value type:
  • java.util.Set – java.util.HashSet is used to store value.
  • java.util.SortedSet – java.util.TreeSet is used to store value.
  • java.util.List – java.util.ArrayList is used to store value. Preserves the position with an index column
  • Bag semantics – java.util.ArrayList is used to store valre however the position is not preserved.
  • java.util.Map – java.util.HashMap is used to store value.
  • java.util.SortedMap – java.util.TreeMap is used to store value.
Let’s say we want to store Phones for a Student. There are more than one Phone for a Student. So we will have two tables corresponding to Student and Phone. However we do not want to expose Phone
Table STUDENT
STUDENT_ID

...

Table PHONE
STUDENT_ID

NUMBER

...

STUDENT_ID is the foreign key and PHONE table has no primary key. To map the Phone collection as a Set in the Student Entity class
Student class
...

@org.hibernate.annotations.CollectionOfElements(targetElement = java.lang.String.class)

@JoinTable( name="PHONE",joinColumns = @JoinColumn(name="STUDENT_ID"))

@Column(name="PHONE_NO")

public Set<String> getPhones() {
...

The lifecycle of Phone is tightly coupled to Student. Also Phone table is not exposed as an entity. If the Set need to be sorted
...

@org.hibernate.annotations.CollectionOfElements(targetElement = java.lang.String.class)

@JoinTable( name="PHONE",joinColumns = @JoinColumn(name="STUDENT_ID"))

@Column(name="PHONE_NO")

@org.hibernate.annotations.Sort(type=org.hibernate.annotations.SortType.NATURAL)
public Set<String> getPhones() {
...

A comparator can also be used for Sort type.
To map the Phone collection as a list
...

@org.hibernate.annotations.CollectionOfElements

@JoinTable( name="PHONE",joinColumns = @JoinColumn(name="STUDENT_ID"))

@org.hibernate.annotations.IndexColumn(name=“INDEX_POSITION", base =1)

@Column(name="PHONE_NO")
public List<String> getPhones() {
    return phones;
}
---

Here the index is mapped to a INDEX_POSITION column in the table and preserves the ordering. If the index is not given, this works like a Bag. Bag is a list but does not preserves the position.
To map Phone as a map where PHONE_NAME will act as key and PHONE_NO as value from the PHONE table. To map it
...

@org.hibernate.annotations.CollectionOfElements

@JoinTable( name="PHONE",joinColumns = @JoinColumn(name="STUDENT_ID"))

@org.hibernate.annotations.MapKey(columns = @Column(name="PHONE_NAME"))

@Column(name="PHONE_NO")
public Map<String,String> getPhones() {
...

Here the Phone table is mapped directly as a collection. We can also expose Phone as a value object. In this case define Phone as a class
@Embeddable

public class PhoneValue {

    

  protected Student student;

  protected String name;
  protected String phoneNumber;
    
  @org.hibernate.annotations.Parent
  public Student getStudent() {
    return student;
 }
 ...

Also in the above case we maintain a back pointer for Student so that we can navigate from Phone to Student. To define the collection of embedded object in Student class
...

protected Collection<PhoneValue> phoneValues = new ArrayList<PhoneValue>();

@org.hibernate.annotations.CollectionOfElements

@JoinTable(name = "Student_Phone_Value",joinColumns = @JoinColumn(name="STUDENT_ID"))

@CollectionId(columns= @Column(name="STUDENT_PHONE_VALUE_ID"),    

                               type=@org.hibernate.annotations.Type(type="long"),

                       generator="sequence")
public Collection<PhoneValue> getPhoneValues() {
       return phoneValues;
}
...    

Hibernate collection mapping is a way of mapping the collection table as values. The lifecycle of the the collections are tightly bound to the collection of the owning entity.

More write-ups on Hibernate

Mapping Properties in Hibernate

In this section we will look into how to map the different types of properties. All properties if mapped with annotation are by default persistent. This is different from when XML is used for mapping. In XML mapping, only the properties explicitly mapped are persistent.
Transient
If a property needs to be stopped from being persistent.
@Transient

    public int getActive() {

        return active;

    }
Now this property does not becomes part of persistent mechanism. The property resides only in the Java layer.
Temporal
Allow to map java.util.Date and java.util.Calender. In SQL the date are differentiated by whether it's a date, time or a timestamp. Timestamp has both date and time. However in Java the date is always a timestamp. It has all the information. So we have to deal with this mismatch also.
//Options for TemporalType

 //   - DATE

 //   - TIME

 //   - TIMESTAMP
@Temporal(TemporalType.TIMESTAMP)
    public Date getBirthDate() {
        return birthDate;
    }

Large Data
Large data is characterized by whether it is a binary large data (BLOB) or character larger date (CLOB)
  • Blob - byte[], Byte[]
  • Clob - char[], Character[]
BLOB and CLOB both are mapped with Lob annotation
@Lob

public byte[] getPicture() {

        return picture;

}
Enumeration
Enumeration are type safe way of restricting the choice in Java. Let's say we have enum defined in Java as
public enum StudentType {

    CURRENT,

    ALUMNI

}
to specify the usage of this enum in entity
@Enumerated(EnumType.STRING)

public StudentType getStudentType() {

        return studentType;

    }    
Enum Type can be String or Ordinal. If String is specified, in the database CURRENT or ALUMNI is stored. If ordinal is specified 0 or 1 is saved. If Enum Type is omitted ORDINAL is taken as default.
Derived Properties
Derived properties are useful to calculate formulas or derived values which is not stored in database but important for business purpose.
@org.hibernate.annotations.Formula("(MARKS/TOTAL_MARKS)*100")

    public Long getPercentage() {

        return percentage

    }
The value is evaluated while fetching the entity so it might be outdated at other times. It's the responsibility of the developer to keep it updated.The property appears in the SELECT statement only and does not participates in INSERT or UPDATE statement.Even SQL expression can be passed to the underlying database so there is a chance to build database dependency.SQL functions including SQL subselects can be used.
Handling Generated Values
In DDL we define defaults to many values like SYSDATE for timestamp which means if we do not give value from Java it is automatically generated.After saving if we want to refresh the object in Java layer, we will have to call a refresh on the object. The other way is that we can tell Hibernate to refresh the value automatically after an insertion. Make sure that you have dynamicInsert set to false otherwise null value will be inserted into the database.
    @Column(updatable= false, insertable = false)

    @org.hibernate.annotations.Generated

                  (org.hibernate.annotations.GenerationTime.INSERT)

    public Double getPendingAmount() {
        return pendingAmount;
    }

Embedded classes
Embedded classes are useful for bringing fine domain modeling. We have one table but more classes mapped to it to bring rich domain model. Though Student table contains all the details for Student and his address, we will map it to two classes.
Student Table
 Student_Id

 Name

 City

 Country
Let's have city and country mapped to a different class Address. We put Embeddable annotation on it to tell that it will be used as an embedded property in an entity class
@Embeddable

public class Address {    

    protected String city;

    protected String country;
    
    @Column(name = "ADD_CITY")
    public String getCity() {

In the Student class
private Address address;

@Embedded

public Address getAddress() {

      return address;
 }
//Setter method

By default this will mapped to ADD_CITY column name as mapped in Address. To get it mapped to CITY column as in Student table, we ill have to override the column name.

   

   @Embedded

   @AttributeOverride (name= "city",column = @Column(name="CITY"))
    public Address getAddress() {
        return address;
    }

Now in this case we can navigate to Address object by holding a reference of Student object. But it's not possible to navigate from Address object to Student object. To build the bi directional navigation in Address entity

In Address class


    @org.hibernate.annotations.Parent
    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {

        this.student = student;

    }  


Mapping Id of Table to Class in Hibernate

Identity of an object is the property which is mapped to primary key of the row in the database. The id of the entity is mapped by @Id annotation
@Entity

@Table(name="Student")

public class Student {

    
    //Id will correspond the primary key in the database
    private Long id;
    protected String name;
    
    ...

    //Id - Represents that it is a primary key column

    //GeneratedValue - How the key to be generated

    //column - Column to which this property is mapped

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="STUDENT_ID")    
    public Long getId() {
        return id;
    }
    
    public void setId(Long id) {
        this.id = id;
    }    
...

Hibernate supports many identifier generation strategy which supports all the major databases
Hibernate does not allows to change the Id once it has been set. It throws an exception if an attempt is made
student = new Student();

Long studentId = (Long)session.save(student);

//student.setId(80L); - This will throw an exception

Right now JPA supports limited identifier generation strategy. So if the hibernate generation strategies need to be employed than do as follows:
@Entity

@org.hibernate.annotations.GenericGenerator(

    name="hibernate-native",

    strategy="native")
public class Student{
    
    private Long id;
    protected String name;
    
    @Id
    @GeneratedValue(generator="hibernate-native")
    @Column(name="STUDENT_ID")
    public Long getId() {
        return id;
    }

It's possible to write one's own identifier generation strategy by implementing IdentifierGenerator interface. However try to use one of the existing generator as Hibernate already has very rich identifier generators.

More write-ups on Hibernate

Mapping Class in Hibernate

The basic notion of ORM is mapping between class and table. A class is considered to be an entity when it gets the Entity annotation.
Entity
@Entity

public class Student {

We can provide a name to an entity. By default the name is the class name. We can give another name to entity so that conflicts do not occur because of same name entity sitting in different package
@Entity(name="anotherStudent")

public class Student {

By default this entity gets mapped to a table with same name. If we want to specify the table name explicitly
@Entity

@Table(name="Student")

public class Student {

Dynamic SQL Generation
Hibernate by default generates the SQL for CRUD right in the beginning. This also means that even if we just update one property of the entity, still the update is issued for all the properties. If we want hibernate to generate SQL at runtime only taking care of changed entity only than use Entity annotation coming from hibernate.
Let's introduce a property in Student class age
@Entity

@Table(name="Student")

public class Student {

    

    //Id will correspond the primary key in the database
    private Long id;
    protected String name;
    protected Integer age;
    
       //Getters and Setters
        ...
    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {

        this.age = age;

    }

        ...

Persist the student by making a new Student object and setting show_sql true.
Student student = new Student();

student.setName("oyeJava");

Long studentId = (Long)session.save(student);

The SQL generated by hibernate as seen in console is
insert into Student (STUDENT_ID, age, name) values (null, ?, ?)
Note that though the age has not been set but still the SQL contains the age parameter. Now let's introduce the Entity annotation from Hibernate so that we ask hibernate to generate the SQL at runtime rather than using the pre generated CRUD statement
//dynamicInsert - Include only those properties which are not null in inserting the data

//dynamicUpdate - Include only those properties which have changed

@Entity

@org.hibernate.annotations.Entity(

    dynamicInsert=true,
    dynamicUpdate=true)
public class Student {

The SQL generated at console is
insert into Student (name, STUDENT_ID) values (?, null)
Note that the age field is absent. This is useful when the table has very large number of columns and modification and insertion is done only on smaller number of columns.
Immutability
When we know that an entity is not going to change at runtime. For example older messages fetched from database, than we can ask hibernate to not to do dirty checking for it. This also results in better performance.
@org.hibernate.annotations.Entity(

    dynamicInsert=true,

    dynamicUpdate=true,

    mutable=false

)
public class Student {

More write-ups on Hibernate