Let's create two classes Employee and Address, such that they have the following relation between them.

Employee has-a Address which means a one-to-one mapping between the two and Employee is the owner of the relation.

  1. Owner of the relation means that Owner can exist without the dependent entity but dependent entity cannot stay without the owner entity.
  2. Dependent Entity of Relationship will containes the 'foreign key' ID of the Owner entity. In this case, Address will contian the Employee Id in its table as shown in the table structure below.

This means that Employee can stay without an Address but Address cannot stay without the Employee. In even more simpler words, If employee is deleted his address should also be deleted, but if address is deleted employee should not be deleted.

Employee.java


package com.ekiras.domain;

import javax.persistence.*;
import java.util.Date;

/**
 * @author ekiras
 */
@Entity
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected long id;

    @Temporal(TemporalType.TIMESTAMP)
    protected Date dateCreated;

    @Temporal(TemporalType.TIMESTAMP)
    protected Date lastUpdated;

    private String email;
    private String name;
    private String password;
    
    @OneToOne(mappedBy = "employee",optional = false,cascade = CascadeType.ALL)
    private Address address;


    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", dateCreated=" + dateCreated +
                ", lastUpdated=" + lastUpdated +
                ", email='" + email + '\'' +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
    // getters and setters
}

Address.java


package com.ekiras.domain;

import javax.persistence.*;
import java.util.Date;

/**
 * @author ekiras
 */
@Entity
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @Temporal(TemporalType.TIMESTAMP)
    protected Date dateCreated;

    @Temporal(TemporalType.TIMESTAMP)
    protected Date lastUpdated;

    private String address;

    @OneToOne(fetch = FetchType.LAZY)
    private Employee employee;

    @Override
    public String toString() {
        return "Address{" +
                "id=" + id +
                ", dateCreated=" + dateCreated +
                ", lastUpdated=" + lastUpdated +
                ", address='" + address + '\'' +
                ", employee=" + employee +
                '}';
    }
    // getters and setters
}

Following Tables will be created from the Entities defined above.

mysql> show tables;
+-----------------------+
| Tables_in_jpa_mapping |
+-----------------------+
| address               |
| employee              |
+-----------------------+
2 rows in set (0.00 sec)

mysql> desc employee;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| date_created | datetime     | YES  |     | NULL    |                |
| email        | varchar(255) | YES  |     | NULL    |                |
| last_updated | datetime     | YES  |     | NULL    |                |
| name         | varchar(255) | YES  |     | NULL    |                |
| password     | varchar(255) | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

mysql> desc address;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| address      | varchar(255) | YES  |     | NULL    |                |
| date_created | datetime     | YES  |     | NULL    |                |
| last_updated | datetime     | YES  |     | NULL    |                |
| employee_id  | bigint(20)   | YES  | MUL | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

You can save the object's as shown in the example below

    public void test(){
    
        // create employee object
        Employee employee = new Employee();
        employee.setName("Ekansh");
        employee.setEmail("ekansh@ekiras.com");
        employee.setPassword("pwd");

        // create Address object
        Address address = new Address();
        address.setAddress("Some Address");

        employee.setAddress(address);
        
        // actual save call for the object
        employeeRepository.save(employee);

    } 

Following are the images that show the working of the One-TO-One mapping.

Initial Interface Initial Interface Initial Interface Initial Interface Initial Interface


Points To Remember

  1. Your Parent class should be annotated with @MappedSuperclass.
  2. Follow the Tutorial : How to handle Inheritence with Entities to know how to wrap common properties of entities to a base class.
  3. To override any property you must
    a. Apply the @AttributeOverride annotation on the class that need to override the property
    b. set name property of @AttributeOverride as the name of the field in super class.
    c. set the column property of @AttributeOverride to override the column definition of the attribute.

Let's say our Base class looks as follows

package com.ekiras.domain.base;

import javax.persistence.*;
import java.util.Date;

/**
* @author ekiras
*/
@MappedSuperclass
public abstract class BaseDomain {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  protected long id;

  @Temporal(TemporalType.TIMESTAMP)
  protected Date dateCreated;

  @Temporal(TemporalType.TIMESTAMP)
  protected Date lastUpdated;

  @Override
  public String toString() {
      return "BaseDomain{" +
              "id=" + id +
              ", dateCreated=" + dateCreated +
              ", lastUpdated=" + lastUpdated +
              '}';
  }
  // getters and setters
}

We can override the id field of the BaseDomain class in inheriting class as follows

package com.ekiras.domain;

import com.ekiras.domain.base.BaseDomain;

import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.Entity;

/**
 * @author ekiras
 */
@Entity
@AttributeOverride(name = "id",column = @Column(name = "userId"))
public class User extends BaseDomain{

    private String email;
    private String name;
    private String password;

    // getters and setters
}

As shown in the code above we have used @AttributeOverride

@AttributeOverride(name = "id",column = @Column(name = "userId"))

Here, name= "id" states that we are going to override the mapping for the id field of the super class. column = @Column(name = "userId") states the new configuration of the id defined in the super class. Here we simple change the name of the column for table user defined by class User.

This will create the table user as shown below.

mysql> show tables;
+-----------------------+
| Tables_in_jpa_mapping |
+-----------------------+
| user                  |
+-----------------------+
1 row in set (0.00 sec)

mysql> desc user;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| user_id      | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| date_created | datetime     | YES  |     | NULL    |                |
| last_updated | datetime     | YES  |     | NULL    |                |
| email        | varchar(255) | YES  |     | NULL    |                |
| name         | varchar(255) | YES  |     | NULL    |                |
| password     | varchar(255) | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

@AttributeOverride

May be applied to an entity that extends a mapped superclass or to an embedded field or
property to override a basic mapping or id mapping defined by the mapped superclass or embeddable class (or embeddable class of one of its attributes).

May be applied to an element collection containing instances of an embeddable class or to a map collection whose key and/or value is an embeddable class. When AttributeOverride is applied to a map, "key." or "value." must be used to prefix the name of the attribute that is being overridden in order to specify it as part of the map key or map value.

To override mappings at multiple levels of embedding, a dot (".") notation form must be used in the name element to indicate an attribute within an embedded attribute. The value of each identifier used with the dot notation is the name of the respective embedded field or property.



Also Read

  1. How to handle inheritance with Entities

Points to Remember

  1. Mark your Base Entity class with annotation @MappedSuperclass.
  2. Define all common fields and their getter setters in this class.
  3. Make the base class abstract.
  4. Make all fields as protected so that they can be accessed in inheriting class without getters and setter.
  5. You can also define @PrePersist and @PreUpdate in this class.

Fields that should be in the Base Entity

Your Base Entity class should have only those field that need to be common for all your entities that will inherit this class.
Sample Base Entity that you should use might look as follows

package com.ekiras.domain.base;

import javax.persistence.*;
import java.util.Date;

/**
 * @author ekiras
 */
@MappedSuperclass
public class BaseDomain {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    protected long id;

    @Temporal(TemporalType.TIMESTAMP)
    protected Date dateCreated;

    @Temporal(TemporalType.TIMESTAMP)
    protected Date lastUpdated;

    @Override
    public String toString() {
        return "BaseDomain{" +
                "id=" + id +
                ", dateCreated=" + dateCreated +
                ", lastUpdated=" + lastUpdated +
                '}';
    }
    

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public Date getDateCreated() {
        return dateCreated;
    }

    public void setDateCreated(Date dateCreated) {
        this.dateCreated = dateCreated;
    }

    public Date getLastUpdated() {
        return lastUpdated;
    }

    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }
}

In the above BaseDomain class we have marked it with annotation @MappedSuperclass. This will enforce that no table is created for this class in the database.

@MappedSuperclass

A class designated with the MappedSuperclass annotation can be mapped in the same way as an entity except that the mappings will apply only to its subclasses since no table exists for the mapped superclass itself. When applied to the subclasses the inherited mappings will apply in the context of the subclass tables.

Now, let us inherit this base class in the User Entity class. So the User.java class may be as follows

package com.ekiras.domain;

import com.ekiras.domain.base.BaseDomain;

import javax.persistence.Entity;

/**
 * @author ekiras
 */
@Entity
public class User extends BaseDomain{

    private String email;
    private String name;
    private String password;

    @Override
    public String toString() {
        return super.toString()+" :: User{" +
                "email='" + email + '\'' +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

When we will run the project it will create the following table in the database.

mysql> show tables;
+-----------------------+
| Tables_in_jpa_mapping |
+-----------------------+
| user                  |
+-----------------------+
1 row in set (0.00 sec)

mysql> desc user;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| date_created | datetime     | YES  |     | NULL    |                |
| last_updated | datetime     | YES  |     | NULL    |                |
| email        | varchar(255) | YES  |     | NULL    |                |
| name         | varchar(255) | YES  |     | NULL    |                |
| password     | varchar(255) | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)

This shows that,

  1. No table is created for the BaseDomain class.
  2. All the field od the BaseDmain class are included in the inherting class User.

How to create a jar file.

We can make a jar file with a single class using the following commands

Here can be replaced by the name of the jar file you want.

1. Create a jar file with single file

jar --create --file=<FileName> <file-1>

2. Create a jar file with multiple files

jar --create --file=<FileName> <file-1> <file-2>

3. Create a jar file with all files in a directory

jar --create --file="<FileName> -C /path/to/dir/ ."

Here -C specifies the directory and . specifies that it need to include all the files in te directory.

Some of the shorthands for the above commands

Option Shorthand
--create -c
--file -f
--module-path -p
--verbose -v
--list -t
--extract -x


How to extract a jar file

jar -xf <FileName>

How to list the contents of a jar file

jar -tf <FileName>

Points To Remember

  1. It is a Creational Design Pattern
  2. It must be used when you have multiple overloaded constructors or setters
  3. Its main purpose it to hide from the user, how the object is to be created.
  4. It is advised to make your constructors private when you are using Builder Design Pattern.

What is Builder Design Pattern

It is a creational design pattern. So it is only responsible for how an object must be created.

There may be scenarios where there is a class with many instance variables that may be needed to create an object of the class. For this you might have to create many overloaded constructors.

For Example we have a class NutritionFacts that has following instance variables

    private int servingSize;
    private int servings;
    private int calories;
    private int fat;
    private int sodium;
    private int carbohydrate;

Then to create the object of the class we can have constructors as follows

  NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27);
  NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0);
  NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 35, 27);
  

As shown in the code above, it is not clear from the code itself what constructor is called for setting values.

This is the best example where we should use Builder Pattern for Building our class objects.

Now, when using Builder Pattern we will be able to tell from the code itself what values are we setting for which instance variable.

For example, if the above constructor were replaces by the following code sample.

     NutritionFacts facts = new NutritionFacts.Builder(100,10)
                .calories(785)
                .carbohydrate(452)
                .fat(24)
                .sodium(8)
                .build();

The above code is in itself readable and tells what values are we setting for variables.

Advantages of Builder Pattern

This makes the setting of variables and paramaters very readable and less error prone.

Disadvantages Of Builder Pattern

  1. If the number of paramaters are not more than 4 or the number of required paramaters are more than this may not be the optimal solution since the cost of making builders will be more.
  2. Another main disadvantage is that your builder should have same number of fields as the class itself, hence the duplicacy of code is more and you need to make changes to both class and Builder when adding or removing any field.

How to Implement Builder Design pattern in Java ?

To implement the Builder Design pattern in Java we will create a Builder Class for making object of our class.

  1. We can have make this Builder class inside our class or even outside the class. How ever it is adviced to to create this class inside the class for which the object will be created. Otherwise you will not be able to make the constructor of the class private. If the construtor is not private then,the user can still make the object with the new keyword.

  2. Also the Builder class should have all the field of the main class.

  3. Builder class should be a static inner class of the Main class and set all the values to its instance variables instead of the Main class

  4. The Builder class should have public setter methods and no getters.

  5. When the build method is called it should build the object depending updon the values passed and return an object.

A sample class may look as follows


public class NutritionFacts {

    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;


    public static class Builder {

        // Required parameters
        private final int servingSize;
        private final int servings;

        // Optional parameters - initialized to default values
        private int calories = 0;
        private int fat = 0;
        private int carbohydrate = 0;
        private int sodium = 0;

        public Builder(int servingSize, int servings) {
            this.servingSize = servingSize;
            this.servings = servings;
        }

        public Builder calories(int val) {
            calories = val;
            return this;
        }

        public Builder fat(int val) {
            fat = val;
            return this;
        }

        public Builder carbohydrate(int val) {
            carbohydrate = val;
            return this;
        }

        public Builder sodium(int val) {
            sodium = val;
            return this;
        }

        public NutritionFacts build() {
            return new NutritionFacts(this);
        }
    }

    private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        calories = builder.calories;
        fat = builder.fat;
        sodium = builder.sodium;
        carbohydrate = builder.carbohydrate;
    }

    public int getServingSize() {
        return servingSize;
    }

    public int getServings() {
        return servings;
    }

    public int getCalories() {
        return calories;
    }

    public int getFat() {
        return fat;
    }

    public int getSodium() {
        return sodium;
    }

    public int getCarbohydrate() {
        return carbohydrate;
    }
}


and now you can build the Object of the class NutritionFacts as follows

NutritionFacts facts = new NutritionFacts.Builder(100,10)
                .calories(785)
                .carbohydrate(452)
                .fat(0)
                .build();



findAll()

This method will find all the items in the groovy collection that matches the IDENTITY closure.

collect()

This method iterates through a collection and transforms each entry element to a new element using IDENTITY closure as a transformer. It returns a new collection of elements copied from the original collection.

Difference between finalAll() and collect() methods


findAll()collect()
findAll() will return the collection or subset of collection that satisfy the Identity closure or a condition collect() will return a new collection or sub set of collection.
findAll() will not modify the entry elements of the collection collect() will modify the elements by Identity closure.
findAll() will return the elements that matches the condition or Identity closure. collect() will return all the elements of the collection based on the transformation specified by the closure.

def list = [1,2,3,4,5];    
    
println list.findAll{it==3}     // [3]  
println list.findAll{it>3}      // [4, 5]  
println list.findAll{it*2}      // [1, 2, 3, 4, 5]  
  
println list.collect{it%2==0}   // [false, true, false, true, false]  
println list.collect{it==2}     // [false, true, false, false, false]  
println list.collect{it*2}      // [2, 4, 6, 8, 10]  

Points To Remember


  • Implement the class Filter.
  • Add @Configuration annotation to the class to register it as a filter bean.
  • Call method 
    • filterChain.doFilter(resquest,response) to continue the request flow
    • Call method sendError to send error,
      ((HttpServletResponse)response).sendError(HttpServletResponse.SC_BAD_REQUEST);
    • Call method sendRedirect to redirect request to error handler
      ((HttpServletResponse)response).sendRedirect("/errorUrl");

How to create a Filter in Spring Boot Application

IN order to make a filter, we have create a class SecurityFilter
  1. package com.ekiras.filter;  
  2.   
  3. import org.springframework.core.Ordered;  
  4. import org.springframework.core.annotation.Order;  
  5. import org.springframework.stereotype.Component;  
  6.   
  7. import javax.servlet.*;  
  8. import javax.servlet.http.HttpServletResponse;  
  9. import java.io.IOException;  
  10.   
  11. /** 
  12.  * @author ekansh 
  13.  */  
  14. @Component  
  15. @Order(Ordered.HIGHEST_PRECEDENCE)  
  16. public class SecurityFilter implements Filter {  
  17.   
  18.     private static final boolean CONDITION = true;  
  19.   
  20.     @Override  
  21.     public void init(FilterConfig filterConfig) throws ServletException {  
  22.   
  23.     }  
  24.   
  25.     @Override  
  26.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
  27.         if(CONDITION==true)  
  28.             chain.doFilter(request,response);  
  29.         else{  
  30.             ((HttpServletResponse)response).setStatus(HttpServletResponse.SC_BAD_REQUEST);  
  31.         }  
  32.   
  33.     }  
  34.   
  35.     @Override  
  36.     public void destroy() {  
  37.   
  38.     }  
  39. }  

This is how you can create the filter and register it in the Spring Boot Application.