Sunday, January 20, 2019

Spring Annotations

Spring Annotations

Annotations Description
@Component, @Repository and @Service @Component annotation is the more generalized form that are considered as candidates for auto-detection when using annotation-based configuration and classpath scanning. This annotation extended to more specific forms such as @Controller, @Repository and @Service.
@Autowired Spring bean dependencies are defined in the XML files, the same can be automatically detected by the Spring container by using the @Autowired annotation. This would eliminate using the XML configurations.
@Qualifier There may be scenarios when we create more than one bean of the same type and want to wire only one of them with a property. This can be controlled using @Qualifier annotation along with the @Autowired annotation.
@Required @Required annotation applies to bean property setter methods and enforces required properties
Difference between @Resource, @Autowired and @Inject This tutorial explains the difference between these three annotations @Resource, @Autowired and @Inject used for injecting the objects.
@Inject and @Named @Inject and @Named annotations are JSR-330 annotations was introduced in Spring 3 as alternative for the spring annotations @Autowired and @Component.
@Resource, @PostConstruct and @PreDestroy This tutorial explains the JSR-250 annotations that are introduced in Spring 2.5, which include @Resource, @PostConstruct and @PreDestroy annotations.
@RestController @RestController annotation is inherited from the @Controller annotation. This annotation is the special version of @Controller annotation for implementing the RESTful Web Services. @RestController has been added as part of the Spring 4 release.
@RequestHeader @RequestHeader annotation for facilitating us to get the header details easily in our controller class. This annotation would bind the header details with the method arguments, and it can be used inside the methods.
@ControllerAdvice @ControllerAdvice annotation used for defining the exception handler with specific exception details for each method If any exception thrown on any part of the application will be handled by this component.
@ModelAttribute @ModelAttribute annotation can be used as the method arguments or before the method declaration. The primary objective of this annotation to bind the request parameters or form fields to an model object.
@Conditional This tutorial explains one of the new features introduced in spring 4, conditional annotation type.
@Query This spring data series tutorial explains @Query annotation and how to create custom query using the @Query annotation.
@Profile This tutorial explain how to enable profiles in your spring application for different environments.
@Configuration Instead of using the XML files, we can use plain Java classes to annotate the configurations by using the @Configuration annotation. If you annotate a class with @Configuration annotation, it indicates that the class is used for defining the beans using the @Bean annotation.
@PathVariable We have to use @PathVariable for accepting the customized or more dynamic parameters in the request paths.
@Controller, @RequestMapping, @RequestParam, @SessionAttributes and @InitBinder This tutorial explains you some of the key annotations that are related to Spring MVC applications @Controller, @RequestMapping, @RequestParam, @SessionAttributes and @InitBinder
Difference between @RequestParam and @PathVariable This tutorial explains you what is the difference between the two annotations @RequestParam and @PathVariable.
@RequestMapping @RequestMapping annotation is used for mapping web requests to a particular handler classes or handler methods.
@Value  This tutorial shows how to load the properties file values using the @Value annotation.
@Import @Import is the annotation used for consolidating all the configurations defined in various configuration files using @Configuration annotation.
@Transactional Use annotation @Transactional in order to define a particular method that should be within a transaction.
@SpringBootApplication This is annotation is the heart of spring boot application. @SpringBootApplication indicates that it is the entry point for the spring boot application.
@EnableAutoConfiguration This example demonstrates how to use the @EnableAutoConfiguration annotations for auto-configuring the spring boot applications.
@EnableCaching @EnableCaching annotation is the annotation-driven cache management feature in the spring framework. This annotation has been added to the spring since the version 3.1.

Spring MVC Request Processing


 request lifecycle
  1. DispatcherServlet receives the request.
  2. DispatcherServlet dispatches the task of selecting an appropriate controller to HandlerMapping. HandlerMapping selects the controller which is mapped to the incoming request URL and returns the (selected Handler) and Controller to DispatcherServlet.
  3. DispatcherServlet dispatches the task of executing of business logic of Controller to HandlerAdapter.
  4. HandlerAdapter calls the business logic process of Controller.
  5. Controller executes the business logic, sets the processing result in Model and returns the logical name of view to HandlerAdapter.
  6. DispatcherServlet dispatches the task of resolving the View corresponding to the View name to ViewResolver. ViewResolver returns the View mapped to View name.
  7. DispatcherServlet dispatches the rendering process to returned View.
  8. View renders Model data and returns the response.

Spring mvc HandlerMapping VS HandlerAdapter

Sol :

  1. DispatcherServlet dispatches the task of executing of business logic of Controller to HandlerAdapter.
  2. HandlerAdapter calls the business logic process of Controller.
  3. Controller executes the business logic, sets the processing result in Model and returns the logical name of view to HandlerAdapter.

Sunday, January 13, 2019

Difference Between Merge And Update Methods In Hibernate?

  • update() and merge() methods in hibernate are used to convert the object which is in detached state into persistence state.[  But there are different situation where we should be used update() and where should be used merge() method in hibernate  ]
  •  Example:
Employee emp1 = new Employee();
emp1.setEmpId(100);
emp1.setEmpName("Dinesh");
//create session
Session session1 = createNewHibernateSession();
session1.saveOrUpdate(emp1);
session1.close();
//emp1 object in detached state now

emp1.setEmpName("Dinesh Rajput");//Updated Name
//Create session again
Session session2 = createNewHibernateSession();
Employee emp2 =(Employee)session2.get(Employee.class, 100);
//emp2 object in persistent state with id 100

//below we try to make on detached object with id 100 to persistent state by 
using update method of hibernate
session2.update(emp1);//It occurs the exception NonUniqueObjectException 
because emp2 object is having employee with same empid as 100. In order 
//to avoid this exception we are using merge like given below instead of
 session.update(emp1);

session2.merge(emp1); //it merge the object state with emp2
session2.update(emp1); //Now it will work with exception
 

What's the advantage of persist() vs save() in Hibernate?

persist() is well defined. It makes a transient instance persistent. However, it doesn't guarantee that the identifier value will be assigned to the persistent instance immediately, the assignment might happen at flush time. The spec doesn't say that, which is the problem I have with persist().
persist() also guarantees that it will not execute an INSERT statement if it is called outside of transaction boundaries. This is useful in long-running conversations with an extended Session/persistence context.
A method like persist() is required.
save() does not guarantee the same, it returns an identifier, and if an INSERT has to be executed to get the identifier (e.g. "identity" generator, not "sequence"), this INSERT happens immediately, no matter if you are inside or outside of a transaction. This is not good in a long-running conversation with an extended Session/persistence context.

Saturday, January 12, 2019

Hibernate IDENTITY vs SEQUENCE entity identifier generators?

  • The IDENTITY generator will always require a database hit for fetching the primary key value without waiting for the flush to synchronize the current entity state transitions with the database.
  •  IDENTITY generator doesn't play well with Hibernate write-behind first level cache strategy.
  • Insert a row without specifying a value for the ID. After inserting the row, ask the database for the last generated ID.
  • The GenerationType.IDENTITY is the easiest to use but not the best one from a performance point of view.

How Does Spring @Transactional Really Work?

JPA on itself does not provide any type of declarative transaction management. When using JPA outside of a dependency injection container, transactions need to be handled programmatically by the developer

If two method have same request mapping in controller then which method should be execute?


Can an abstract class have a constructor?

Yes, an abstract class can have a constructor. Consider this:
abstract class Product { 
    int multiplyBy;
    public Product( int multiplyBy ) {
        this.multiplyBy = multiplyBy;
    }

    public int mutiply(int val) {
       return multiplyBy * val;
    }
}

class TimesTwo extends Product {
    public TimesTwo() {
        super(2);
    }
}

class TimesWhat extends Product {
    public TimesWhat(int what) {
        super(what);
    }
}

Spring can you autowire inside an abstract class?

I have that kind of spring setup working
an abstract class with an autowired field
public abstract class AbstractJobRoute extends RouteBuilder {

    @Autowired
    private GlobalSettingsService settingsService;
and several children defined with @Component annotation.

Monday, January 7, 2019

Can we use Filter instead of Servlet?

A filter is an object that can transform the header and content (or both) of a request or response. Filters differ from web components in that filters usually do not themselves create a response. Instead, a filter provides functionality that can be “attached” to any kind of web resource.

How do I automatically redirect the currently opened page to the login page when the session expires?

<meta http-equiv="refresh" content="${pageContext.session.maxInactiveInterval};url=sessionexpired.jsp">

Session validation filter which logs off the user when session is expired?

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    HttpSession session = request.getSession(false);

    if (session == null || session.getAttribute("user") == null) {
        response.sendRedirect("login"); // No logged-in user found, so redirect to login page.
    } else {
        chain.doFilter(req, res); // Logged-in user found, so just continue request.
    }
}

How to create and destroy session in Spring REST Webservice called from Mobile client?

My Web-service Method is and i want to access this method by mobile client :- 


   @RequestMapping(value = "/login", method = RequestMethod.POST, 
headers="Accept=application/json")
     public @ResponseBody List<LogInStatus> getLogIn(@RequestBody LogIn person ,  
HttpServletRequest request) {   
              // Call service here
             List<LogInStatus> lList = logInService.getUser(person);
//service method and then in DAO database method is there

             return lList;
     }
 

sol: 

You don't need to create session manually - this is done by servlet container.
You can obtain session from HttpServletRequest
HttpSession session = request.getSession(); or just add it as a method parameter, and Spring MVC will inject it for you:
public @ResponseBody List<LogInStatus> getLogIn(@RequestBody LogIn person , HttpServletRequest request, HttpSession httpSession) You then can save user details in session via setAttribute()/getAttribute().
 
 
 
 
 
 
 
 

Thursday, January 3, 2019

Hibernate JPA Cascade Types?

We learned about mapping associated entities in hibernate already in previous tutorials such as one-to-one mapping and one-to-many mappings. There we wanted to save the mapped entity whenever relationship owner entity got saved. To enable this we had use “CascadeType” attribute. In this JPA Cascade Types tutorial, we will learn about various type of available options for cascading via CascadeType.

How JPA Cascade Types Work?

Before moving forward, let’s look at how this cascade type attribute is defined in your code. Let’s have an example for more clear understanding. Take a scenario where an Employee can have multiple Accounts; but one account must be associated with only one employee. Let’s create entities with minimum information for sake of clarity.
EmployeeEntity.java
@Entity
@Table(name = "Employee")
public class EmployeeEntity implements Serializable
{
    private static final long serialVersionUID = -1798070786993154676L;
    @Id
    @Column(name = "ID", unique = true, nullable = false)
    private Integer           employeeId;
    @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
    private String            firstName;
    @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)
    private String            lastName;
 
    @OneToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name="EMPLOYEE_ID")
    private Set<AccountEntity> accounts;
 
    //Getters and Setters Ommited
}
AccountEntity.java
@Entity
@Table(name = "Account")
public class AccountEntity implements Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "ID", unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer           accountId;
    @Column(name = "ACC_NO", unique = false, nullable = false, length = 100)
    private String            accountNumber;
 
    @OneToOne (mappedBy="accounts",  fetch = FetchType.LAZY)
    private EmployeeEntity employee;
 
}
Look at the bold line in above source code for EmployeeEntity.java. It defines “cascade=CascadeType.ALL” and it essentially means that any change happened on EmployeeEntity must cascade to AccountEntity as well. If you save an employee, then all associated accounts will also be saved into database. If you delete an Employee then all accounts associated with that Employee also be deleted. Simple enough.
But what if we only want to cascade only save operations but not delete operation. Then we need to clearly specify it using below code.
@OneToMany(cascade=CascadeType.PERSIST, fetch = FetchType.LAZY)
@JoinColumn(name="EMPLOYEE_ID")
private Set<AccountEntity> accounts;
Now only when save() or persist() methods are called using employee instance then only accounts will be persisted. If any other method is called on session, it’s effect will not affect/cascade to accounts.

JPA Cascade Types

The cascade types supported by the Java Persistence Architecture are as below:
  1. CascadeType.PERSIST : cascade type presist means that save() or persist() operations cascade to related entities.
  2. CascadeType.MERGE : cascade type merge means that related entities are merged when the owning entity is merged.
  3. CascadeType.REFRESH : cascade type refresh does the same thing for the refresh() operation.
  4. CascadeType.REMOVE : cascade type remove removes all related entities association with this setting when the owning entity is deleted.
  5. CascadeType.DETACH : cascade type detach detaches all related entities if a “manual detach” occurs.
  6. CascadeType.ALL : cascade type all is shorthand for all of the above cascade operations.
There is no default cascade type in JPA. By default no operations are cascaded.
The cascade configuration option accepts an array of CascadeTypes; thus, to include only refreshes and merges in the cascade operation for a One-to-Many relationship as in our example, you might see the following:
@OneToMany(cascade={CascadeType.REFRESH, CascadeType.MERGE}, fetch = FetchType.LAZY)
@JoinColumn(name="EMPLOYEE_ID")
private Set<AccountEntity> accounts;
Above cascading will cause accounts collection to be only merged and refreshed.

Hibernate Cascade Types

Now lets understand what is cascade in hibernate in which scenario we use it.
Apart from JPA provided cascade types, there is one more cascading operation in hibernate which is not part of the normal set above discussed, called “orphan removal“. This removes an owned object from the database when it’s removed from its owning relationship.
Let’s understand with an example. In our Employee and Account entity example, I have updated them as below and have mentioned “orphanRemoval = true” on accounts. It essentially means that whenever I will remove an ‘account from accounts set’ (which means I am removing the relationship between that account and Employee); the account entity which is not associated with any other Employee on database (i.e. orphan) should also be deleted.
EmployeeEntity.java
@Entity
@Table(name = "Employee")
public class EmployeeEntity implements Serializable
{
    private static final long serialVersionUID = -1798070786993154676L;
    @Id
    @Column(name = "ID", unique = true, nullable = false)
    private Integer           employeeId;
    @Column(name = "FIRST_NAME", unique = false, nullable = false, length = 100)
    private String            firstName;
    @Column(name = "LAST_NAME", unique = false, nullable = false, length = 100)
    private String            lastName;
 
    @OneToMany(orphanRemoval = true, mappedBy = "employee")
    private Set<AccountEntity> accounts;
    
}
AccountEntity.java
@Entity (name = "Account")
@Table(name = "Account")
public class AccountEntity implements Serializable
{
    private static final long serialVersionUID = 1L;
    @Id
    @Column(name = "ID", unique = true, nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Integer           accountId;
    @Column(name = "ACC_NO", unique = false, nullable = false, length = 100)
    private String            accountNumber;
 
    @ManyToOne
    private EmployeeEntity employee;
}
TestOrphanRemovalCascade.java
public class TestOrphanRemovalCascade
{
   public static void main(String[] args)
   {
      setupTestData();
       
      Session sessionOne = HibernateUtil.getSessionFactory().openSession();
      org.hibernate.Transaction tx = sessionOne.beginTransaction();
       
      //Load the employee in another session
      EmployeeEntity employee = (EmployeeEntity) sessionOne.load(EmployeeEntity.class, 1);
      //Verify there are 3 accounts
      System.out.println("Step 1 : " + employee.getAccounts().size());
       
      //Remove an account from first position of collection
      employee.getAccounts().remove(employee.getAccounts().iterator().next());
       
      //Verify there are 2 accounts in collection
      System.out.println("Step 2 : " + employee.getAccounts().size());
       
      tx.commit();
      sessionOne.close();
       
      //In another session check the actual data in database
      Session sessionTwo = HibernateUtil.getSessionFactory().openSession();
      sessionTwo.beginTransaction();
       
      EmployeeEntity employee1 = (EmployeeEntity) sessionTwo.load(EmployeeEntity.class, 1);
      //Verify there are 2 accounts now associated with Employee
      System.out.println("Step 3 : " + employee1.getAccounts().size());
       
      //Verify there are 2 accounts in Account table
      Query query = sessionTwo.createQuery("from Account a");
      @SuppressWarnings("unchecked")
      List<AccountEntity> accounts = query.list();
      System.out.println("Step 4 : " + accounts.size());
       
      sessionTwo.close();
       
      HibernateUtil.shutdown();
   
    
   private static void setupTestData(){
      Session session = HibernateUtil.getSessionFactory().openSession();
      session.beginTransaction();
       
      //Create Employee
      EmployeeEntity emp = new EmployeeEntity();
      emp.setEmployeeId(1);
      emp.setFirstName("Lokesh");
      emp.setLastName("Gupta");
      session.save(emp);
       
      //Create Account 1
      AccountEntity acc1 = new AccountEntity();
      acc1.setAccountId(1);
      acc1.setAccountNumber("11111111");
      acc1.setEmployee(emp);
      session.save(acc1);
       
      //Create Account 2
      AccountEntity acc2 = new AccountEntity();
      acc2.setAccountId(2);
      acc2.setAccountNumber("2222222");
      acc2.setEmployee(emp);
      session.save(acc2);
       
      //Create Account 3
      AccountEntity acc3 = new AccountEntity();
      acc3.setAccountId(3);
      acc3.setAccountNumber("33333333");
      acc3.setEmployee(emp);
      session.save(acc3);
             
      session.getTransaction().commit();
      session.close();
   }
}
 
Output:
 
Hibernate: insert into Employee (FIRST_NAME, LAST_NAME, ID) values (?, ?, ?)
Hibernate: insert into Account (ACC_NO, employee_ID, ID) values (?, ?, ?)
Hibernate: insert into Account (ACC_NO, employee_ID, ID) values (?, ?, ?)
Hibernate: insert into Account (ACC_NO, employee_ID, ID) values (?, ?, ?)
Hibernate: select employeeen0_.ID as ID1_1_0_, employeeen0_.FIRST_NAME as FIRST_NA2_1_0_, employeeen0_.LAST_NAME as
LAST_NAM3_1_0_ from Employee employeeen0_ where employeeen0_.ID=?
Hibernate: select accounts0_.employee_ID as employee3_1_0_, accounts0_.ID as ID1_0_0_, accounts0_.ID as ID1_0_1_,
accounts0_.ACC_NO as ACC_NO2_0_1_, accounts0_.employee_ID as employee3_0_1_ from Account accounts0_ where accounts0_.employee_ID=?
Step 1 : 3
Step 2 : 2
Hibernate: delete from Account where ID=?
Hibernate: select employeeen0_.ID as ID1_1_0_, employeeen0_.FIRST_NAME as FIRST_NA2_1_0_, employeeen0_.LAST_NAME as
LAST_NAM3_1_0_ from Employee employeeen0_ where employeeen0_.ID=?
Hibernate: select accounts0_.employee_ID as employee3_1_0_, accounts0_.ID as ID1_0_0_, accounts0_.ID as ID1_0_1_,
accounts0_.ACC_NO as ACC_NO2_0_1_, accounts0_.employee_ID as employee3_0_1_ from Account accounts0_ where accounts0_.employee_ID=?
Step 3 : 2
Hibernate: select accountent0_.ID as ID1_0_, accountent0_.ACC_NO as ACC_NO2_0_, accountent0_.employee_ID as employee3_0_
from Account accountent0_
Step 4 : 2
It’s a very good way of removing the matching/mismatching items from a collection (i.e. many-to-one or one-to-many relationships). You just remove the item from collection and hibernate take care of rest of the things for you. It will check whether entity is referenced from any place or not; If it is not then it will delete the entity from database itself.
Let me know of your thoughts and questions on hibernate 5 cascade types or JPA cascade types, if any.

What is the difference between cascade and orphan removal from DB?

[ @OneToMany(cascade=REMOVE, mappedBy="customer")
public List<Order> getOrders() { ... }
and

@OneToMany(mappedBy="customer", orphanRemoval="true")
public List<Order> getOrders() { ... } ]
 
Solution: 
  CascadeType.REMOVE indicates that remove operations should be
  cascaded automatically to entity objects that are referenced by that
  field of other entity.  
@Entity
class Employee {
     :
    @OneToOne(cascade=CascadeType.REMOVE)
    private Address address;
     :
}
 
Orphan Removal
JPA 2 supports an additional and more aggressive remove cascading mode which can be specified using the orphanRemoval element of the @OneToOne and @OneToMany annotations:
 
@Entity class Employee {
   
 @OneToOne(orphanRemoval=true) 
 private Address address;  

 }
 

Hibernate FetchMode?


Example application

To demonstrate the different fetchmodes I’ve created a small example application. This example has a Hibernate mapping for the following database schema:
ExampleDB_Diagram
A customer has zero or more invoices and each invoice has a total amount. This example will retrieve all customers, get their invoices, and calculate the total amount over all customers.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
private void findTotalAmountForAllInvoice() throws HibernateException {
Session session = sessionFactory.openSession();
System.out.println("Load all Customers:");
Criteria crit = session.createCriteria(Customer.class);
@SuppressWarnings("unchecked")
List<Customer> customers = crit.list();
System.out.println("Number of Customers: " + customers.size());
BigDecimal allCustomerTotal = BigDecimal.ZERO;
for (Customer customer : customers) {
System.out.println(String.format("Fetch the collection of Invoices for
Customer %s %s", customer.getFirstName(), customer.getLastName()));
Set<Invoice> invoices = customer.getInvoices();
for (Invoice invoice : invoices) {
allCustomerTotal = allCustomerTotal.add(invoice.getTotal());
}
}
System.out.println("Total amount for all invoices: "+ allCustomerTotal.toString());
session.close();
}
You may download the example here. The zip contains a Gradle project. To run the example install gradle and run gradle run in the directory containing the build.gradle file.

Default Hibernate FetchMode: SELECT

You can explicitly set the Hibernate FetchMode in the Customer class by annotating the invoices collection:

1
2
3
@OneToMany(mappedBy = "customer")
@Fetch(FetchMode.SELECT)
private Set<Invoice> invoices;
Running the example gives the following output:


1
2
3
4
5
6
7
8
9
10
11
12
13
Load all Customers:
Hibernate: select this_.id as id1_0_0_, this_.city as city2_0_0_, this_.firstName as...
Number of Customers: 50
Fetch the collection of Invoices for Customer Laura Steel
Hibernate: select invoices0_.CUSTOMERID as CUSTOMER3_0_1_, invoices0_.id as id1_1_1_, ...
Fetch the collection of Invoices for Customer Susanne King
Hibernate: select invoices0_.CUSTOMERID as CUSTOMER3_0_1_, invoices0_.id as id1_1_1_,...
... and so for each Customer
Total amount for all invoices: 121157
The Hibernate FetchMode SELECT generates a query for each Invoice collection loaded. In total that gives 1 query to load the Customers and 50 additional queries to load the Invoice collections.
This behavior is commonly named the N + 1 select problem. Executing 1 query will trigger N additional queries, where N is the amount of results returned from the first query.

Hibernate FetchMode: SELECT with BatchSize

SELECT has an optional configuration annotation called BatchSize:

1
2
3
4
@OneToMany(mappedBy = "customer")
@Fetch(FetchMode.SELECT)
@BatchSize(size=25)
private Set<Invoice> invoices;
This changes the output to:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Load all Customers:
Hibernate: select this_.id as id1_0_0_, this_.city as city2_0_0_, this_.firstName as ...
Number of Customers: 50
Fetch the collection of Invoices for Customer Laura Steel
Hibernate: select invoices0_.CUSTOMERID as CUSTOMER3_0_1_, invoices0_.id as id1_1_1_,...
Fetch the collection of Invoices for Customer Susanne King
Fetch the collection of Invoices for Customer Anne Miller
.. 23 additional collection fetches without a query
Fetch the collection of Invoices for Customer Sylvia Steel
Hibernate: select invoices0_.CUSTOMERID as CUSTOMER3_0_1_, invoices0_.id as id1_1_1_, ...
Fetch the collection of Invoices for Customer James Clancy
Fetch the collection of Invoices for Customer Bob Sommer
.. 23 additional collection fetches without a query
Total amount for all invoices: 121157
In this example BatchSize reduces the total amount of queries to 3. One to load the Customers and two additional queries to load the Invoice collections for all customers. To put it simple: When an Invoice collection is loaded for a specific Customer, Hibernate will try to load the Invoice collection for up to 25 additional Customer entities which are currently in the session. The example has 50 Customers so loading the 50 collections of Invoices takes 2 queries.

Hibernate FetchMode: JOIN

Hibernate FetchMode JOIN tries to load the Customers and the Invoice collections in one query

1
2
3
@OneToMany(mappedBy = "customer")
@Fetch(FetchMode.JOIN)
private Set<Invoice> invoices;
Output:

1
2
3
4
5
6
7
8
9
10
11
12
13
Load all Customers:
Hibernate: select this_.id as id1_0_1_, this_.city as city2_0_1_, this_.firstName as ...
Number of Customers: 71
Fetch the collection of Invoices for Customer Laura Steel
Fetch the collection of Invoices for Customer Susanne King
Fetch the collection of Invoices for Customer Anne Miller
Fetch the collection of Invoices for Customer Michael Clancy
Fetch the collection of Invoices for Customer Sylvia Ringer
Fetch the collection of Invoices for Customer Sylvia Ringer
Fetch the collection of Invoices for Customer Sylvia Ringer
... No additional queries
Total amount for all invoices: 262599
The amount of queries has been reduced to 1 by joining the Customers and Invoice collections. FetchMode JOIN always triggers an EAGER load so the Invoices are loaded when the Customers are. But when we look at the result there seems to be something wrong. There where 71 Customers found and the total amount seems to be different as well. This can be explained by the fact that FetchMode JOIN returns duplicate results when an entity has more then one record in the joined collection! In this example the Customer named Sylvia Ringer has 3 Invoices so she is included 3 times in the result. You’ll have to remove the duplicates yourself (e.g. storing the result in a Set).

Hibernate FetchMode: SUBSELECT

The final Hibernate FetchMode available is the SUBSELECT

1
2
3
@OneToMany(mappedBy = "customer")
@Fetch(FetchMode.SUBSELECT)
private Set<Invoice> invoices;
Output:

1
2
3
4
5
6
7
8
9
Hibernate: select this_.id as id1_0_0_, this_.city as city2_0_0_, this_.firstName as ...
Number of Customers: 50
Fetch the collection of Invoices for Customer Laura Steel
Hibernate: select invoices0_.CUSTOMERID as CUSTOMER3_0_1_, invoices0_.id as id1_1_1_, ...
Fetch the collection of Invoices for Customer Susanne King
Fetch the collection of Invoices for Customer Anne Miller
... No additional queries
Total amount for all invoices: 121157
A SUBSELECT generates one query to load the Customers and one additional query to fetch all the Invoice collections. It is important to notice that all Invoices are loaded for which there is a corresponding Customer in the database. So even Invoice collections for who there are no matching Customers in the session will be retrieved.

Which Hibernate FetchMode should I use?

Which FetchMode to use depends heavily on the application, environment and typical usage. The following guideline should be seen as a rough indication of where to start. Try to play with the setting to see what works best in your application / environment:
FetchMode SELECT
Use this when you want a quick response time when working on a single entity. SELECT creates small queries and only fetches the data which is absolutely needed. The use-case in our example could be an application to which displays one Customer with its Invoices.
BatchSize
BatchSize is useful when working with a fixed set of data. When you have a batch processing 10 Customers at a time a BatchSize of 10 will drastically reduced the number of queries needed.If the BatchSize is not set too high the query will most likely return a manageable amount of data in a reasonable time.
FetchMode JOIN
As indicated you’ll have to worry about duplicated results. On the other hand JOIN creates the least amount of queries. In a high latency environment a single JOIN could be considerable faster then multiple SELECTS. Keep in mind that joining too much data could put a strain on the database.
FetchMode SUBSELECT
If you’ve got an entity of which you know that there aren’t that many of them, and almost all of them are in the session, then SUBSELECT should be a good choice. Just keep in mind that all collections are fetched, even if the parent is not in the session. A SUBSELECT when having a single Customer in session while there are 1000+ in the database will be wasteful.

What is Hibernate N+1 Problems and its Solution

Hibernate n+1 problems only comes for one to many relationship.

Let us see this problem by example – We have Class table with a one-to-many relationship with Student. One Class may have many Student.

Table Class
ID NAME
1 Class1
2 Class2
3 Class3
Table Student
ID CLASS_ID NAME
1 1 Student Name 1
2 1 Student Name 2
3 1 Student Name 3



We have written the Hibernate Class Entity as below.
package com.javaconnect;
@Entity
public class Class {

       @Id
    private Long class_id;
     
    @OneToMany(cascade = ALL, fetch = EAGER)

   @JoinColumn(name = "class_id")

   private List<Student> student = new ArrayList<>();
}

@Entity

public class Student {
   @Id

    private String class_id;
    private String Studentid;     

 }



-- To Get all Departments
SELECT * FROM Department;
-- To get each Employee, get Employee details
SELECT * FROM Employee WHERE Employee.departmentId = ?





The Solution

Avoiding Eager Fetching

This the main reason behind the issue. We should get rid of all the eager fetching from our mapping. We should mark all relationships as Lazy instead.

 Only fetching the data that are actually needed

N+1 problem can happen if the first query populates the primary object and the second query populates all the child objects for each of the unique primary objects returned. Solution for Hibernate N+1 Problem

Using HQL fetch join
You can use the fetch while using the HQL as below example.

1
from Department d join fetch d.employees Employee
Hibernate Generated SQL would be similar as –

1
SELECT * FROM Department d LEFT OUTER JOIN Employee e ON d.id = d.department_id
Using Criteria query

1
2
Criteria criteria = session.createCriteria(Department.class);
criteria.setFetchMode("employees", FetchMode.JOIN);

Wednesday, January 2, 2019

Difference between @NotNull, @NotEmpty and @NotBlank.

@NotNull
CharSequence, Collection, Map or Array object cannot be null, however can be empty.
@NotEmpty
The CharSequence, Collection, Map or Array object cannot be null and not empty (size > 0).
@NotBlank
The string is not null and the length is greater than zero.
Here are the examples:

String test = null;
@NotNull: false
@NotEmpty: false
@NotBlank: false

String test = "";
@NotNull: true
@NotEmpty: false
@NotBlank: false

String test = " ";
@NotNull: true
@NotEmpty: true
@NotBlank: false

String name = "Some text";
@NotNull: true
@NotEmpty: true
@NotBlank: true

Spring Annotations