Hibernate one to many mapping example [Annotation]

We are going to understand hibernate one-to-many relationship on following table structure...

country table holds one-to-many relationship with state table. Where relationship id resides in state table.

Hibernate One to Many mapping

Before we see the complete code, lets first understand how to define relationship in code.

Country.java, State.java

one to many hibernate

Source code (Country.java)
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * @author javaQuery
 * @date 11th April, 2017
 * @Github: https://github.com/javaquery/Examples
 */
@Entity
@Table(name = "country")
public class Country implements Serializable {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

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

    @OneToMany(mappedBy = "country" /*, fetch = FetchType.LAZY*/)
    private Set<State> states = new HashSet<State>();
    
    //getter-setter
}

Source code (State.java)
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

/**
 * @author javaQuery
 * @date 15th June, 2017
 * @Github: https://github.com/javaquery/Examples
 */
@Entity
@Table(name = "state")
public class State implements Serializable{

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "country_id")
    private Country country;

    @Column(name = "name")
    private String name;
    
    //getter-setter
}

Source code (OneToManyMappingExample.java)
import com.javaquery.bean.Country;
import com.javaquery.bean.State;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * Hibernate one to many example.
 * 
 * @author javaQuery
 * @date 15th June, 2017
 * @Github: https://github.com/javaquery/Examples
 */
public class OneToManyMappingExample {

    public static void main(String[] args) {
        try {
            /* Create hibernate configuration. */
            Configuration configuration = new Configuration();
            configuration.configure("com\\javaquery\\database\\hibernate\\hibernate.cfg.xml");

            /* Open session and begin database transaction for database operation. */
            SessionFactory sessionFactory = configuration.buildSessionFactory();
            Session session = sessionFactory.openSession();

            Country country = session.load(Country.class, 1L);
            if(!country.getStates().isEmpty()){
                for (State state: country.getStates()) {
                    System.out.println(state.getName());
                }
            }else{
                System.out.println("No states found!");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Output
Hibernate: 
    select
        country0_.id as id1_1_0_,
        country0_.name as name2_1_0_ 
    from
        country country0_ 
    where
        country0_.id=?
Hibernate: 
    select
        states0_.country_id as country_3_3_0_,
        states0_.id as id1_3_0_,
        states0_.name as name2_3_1_ 
    from
        state states0_ 
    where
        states0_.country_id=?
  
Banglore
Gujarat
Mumbai

Hibernate one to one mapping example [Annotation]

We all understand one-to-one relation in database but when it comes to Hibernate I always stuck at which annotation to use and where should I place it?

We are going to understand the hibernate one-to-one relationship on following table structure.
- country table holds the one-to-one relationship with languages table. Where relationship id resides in country table.
- country table holds the one-to-one relationship with capital table. Where relationship id resides in capital table.


Before we see the complete code, lets first understand how to define relationship in code.

Country.java (country - languages)


Capital.java (country - capital)


Source code (Country.java)
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * @author javaQuery
 * @date 11th April, 2017
 * @Github: https://github.com/javaquery/Examples
 */
@Entity
@Table(name = "country")
public class Country implements Serializable {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

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

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "country")
    private Capital capital;

    @OneToOne
    @JoinColumn(name = "primary_language_id", referencedColumnName = "id")
    private Language language;
 
    //getter-setter
}

Source code (Language.java)
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 * @author javaQuery
 * @date 1th April, 2017
 * @Github: https://github.com/javaquery/Examples
 */
@Entity
@Table(name = "languages")
public class Language implements Serializable{
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;
    
    @Column(name = "language")
    private String language;
 
    //getter-setter
}

Source code (Capital.java)
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

/**
 * @author javaQuery
 * @date 11th April, 2017
 * @Github: https://github.com/javaquery/Examples
 */
@Entity
@Table(name = "capital")
public class Capital implements Serializable{
    
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;
    
    @Column(name = "name")
    private String name;

    
    @OneToOne
    @JoinColumn(referencedColumnName = "id", name = "country_id")
    private Country country;
 
    //getter-setter
}

Source code (OneToOneMappingExample.java)
import com.javaquery.bean.Country;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/**
 * @author javaQuery
 * @date 11th April, 2017
 * @Github: https://github.com/javaquery/Examples
 */
public class OneToOneMappingExample {

    public static void main(String[] args) {
        try {
            /* Create hibernate configuration. */
            Configuration configuration = new Configuration();
            configuration.configure("com\\javaquery\\database\\hibernate\\hibernate.cfg.xml");

            /* Open session and begin database transaction for database operation. */
            SessionFactory sessionFactory = configuration.buildSessionFactory();
            Session session = sessionFactory.openSession();
            
            Country country = session.load(Country.class, 1L);
            System.out.println(country);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Output
Hibernate: 
    select
        country0_.id as id1_1_0_,
        country0_.primary_language_id as primary_3_1_0_,
        country0_.name as name2_1_0_,
        language1_.id as id1_2_1_,
        language1_.language as language2_2_1_,
        capital2_.id as id1_0_2_,
        capital2_.country_id as country_3_0_2_,
        capital2_.name as name2_0_2_ 
    from
        country country0_ 
    left outer join
        languages language1_ 
            on country0_.primary_language_id=language1_.id 
    left outer join
        capital capital2_ 
            on country0_.id=capital2_.country_id 
    where
        country0_.id=?

Country{id=1, name=India, capital=Capital{id=2, name=Delhi}, language=Language{id=2, language=Hindi}}

Google Gson for converting Java object to / from JSON

Following code snippet shows how you can convert Java object to JSON string and vice versa.

Source code (Item.java)
public class Item {

    private Long id;
    private String name;
    private Double price;

    public Item() {
    }
    
    public Item(String name, Double price) {
        this.name = name;
        this.price = price;
    }
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
    
    @Override
    public String toString() {
        return "Item{" + "name=" + name + ", price=" + price + '}';
    }
}

Source code (ObjectToJSON.java)
import com.google.gson.Gson;
import com.javaquery.bean.Item;
import java.util.Arrays;
import java.util.List;

/**
 * Convert Java object to json using gson.
 * @author javaQuery
 * @date 24th March, 2017
 * @Github: https://github.com/javaquery/Examples
 */
public class ObjectToJSON {
    public static void main(String[] args) {
        /* Java object */
        Item iPhone = new Item("iPhone 7", 100.12);
        Item blackBerry = new Item("Black Berry", 50.12);
        List<Item> items = Arrays.asList(iPhone, blackBerry);
        
        Gson gson = new Gson();
        
        /* Convert single Object to JSON */
        String jsonObjectString = gson.toJson(iPhone);
        System.out.println(jsonObjectString);
        
        /* Convert List of Object to JSON */
        String jsonArrayString = gson.toJson(items);
        System.out.println(jsonArrayString);
    }
}

Output
{"name":"iPhone 7","price":100.12}
[{"name":"iPhone 7","price":100.12},{"name":"Black Berry","price":50.12}]

Source code (JSONToObject.java)
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.javaquery.bean.Item;
import java.lang.reflect.Type;
import java.util.List;

/**
 * Convert json string to java object using gson.
 * @author javaQuery
 * @date 24th March, 2017
 * @Github: https://github.com/javaquery/Examples
 */
public class JSONToObject {
    public static void main(String[] args) {
        String jsonObjectString = "{\"name\":\"iPhone 7\",\"price\":100.12}";
        String jsonArrayString = "[{\"name\":\"iPhone 7\",\"price\":100.12},{\"name\":\"Black Berry\",\"price\":50.12}]";
        
        Gson gson = new Gson();
        
        /* Convert JSONObject String to Object */
        Item item = gson.fromJson(jsonObjectString, Item.class);
        System.out.println(item);
        
        /* Convert JSONArray String to Object */
        Type type = new TypeToken<List<Item>>(){}.getType();
        List<Item> items = gson.fromJson(jsonArrayString, type);
        System.out.println(items);
    }
}

Output
Item{name=iPhone 7, price=100.12}
[Item{name=iPhone 7, price=100.12}, Item{name=Black Berry, price=50.12}]

Autoboxing and unboxing conversions in Java

Autoboxing and unboxing in java

Autoboxing and Unboxing
Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called Unboxing.

Autoboxing
Converting primitive values (int, long, float, double...) into an object of the corresponding wrapper class (Integer, Long, Float, Double...) is called autoboxing. The compiler applies autoboxing when a primitive value is:

  • Passed as a parameter to a method that expects an object of the corresponding wrapper class.
  • Assigned to a variable of the corresponding wrapper class.

Autoboxing Example
The given code
/* Passed as a parameter to a method that expects an object of the corresponding wrapper class. */
List<Integer> listIntegers = new ArrayList<>();
for (int i = 1; i < 10; i++){
 listIntegers.add(i); 
}
=====
/* Assigned to a variable of the corresponding wrapper class. */
int x = 10;
Integer y = x;
will be converted by compiler as follow, Here i is autoboxed by Integer.valueOf(i).
List<Integer> listIntegers = new ArrayList<>();
for (int i = 1; i < 10; i++){
 listIntegers.add(Integer.valueOf(i));
}
=====
int x = 10;
Integer y = Interger.valueOf(x);

Unboxing
Converting an object of a wrapper type (Integer, Long, Float, Double...) to its corresponding primitive (int, long, float, double...) value is called unboxing. The compilere applied unboxing when an object of a wrapper class is:

  • Passed as a parameter to a method that expects a value of the corresponding primitive type.
  • Assigned to a variable of the corresponding primitive type.

Unboxing Example
The given code
/* Assigned to a variable of the corresponding primitive type. */
int sum = 0;
for (Integer i : listIntegers){
 if (i % 2 == 0){
  sum += i;
 }    
}
=====
/* Passed as a parameter to a method that expects a value of the corresponding primitive type. */
Integer a = new Integer(10);
Integer b = new Integer(10);

int summation = sum(a, b);

public int sum(int x, int y){
  return x + y;
}
will be converted by compiler as follow because remainder (%) and unary plus (+=) don't apply on wrapper class Integer. Here i % 2 unboxed by i.intValue() % 2 and sum += i unboxed by sum += i.intValue().
int sum = 0;
for (Integer i : listIntegers){
 if (i.intValue() % 2 == 0){
  sum += i.intValue();
 }    
}
=====
Integer a = new Integer(10);
Integer b = new Integer(10);

int summation = sum(a.intValue(), b.intValue());

public int sum(int x, int y){
  return x + y;
}

Running JUnit 5 in Gradle Project

Follow the given step to setup JUnit 5 in Gradle project. Newbies wanna read Setup first gradle project in eclipse.

Step 1. Prepare build.gradle for JUnit 5

Step 1.1. Attach JUnit 5 gradle plugin to project.
apply plugin: 'org.junit.platform.gradle.plugin'

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
    	// Gradle plugin
        classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0-M3'
    }
}
Step 1.2. Add JUnit 5 dependencies.
dependencies {
    // download library for JUnit
    compile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.0.0-M3'
    compile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.0.0-M3'
    compile group: 'org.junit.platform', name: 'junit-platform-runner', version: '1.0.0-M3'
    
    // compile project for testing using Junit Jupiter Api
    testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0-M3")
}
Step 1.3. JUnit 5 configuration.
Properties are self-explanatory.
junitPlatform {
    platformVersion "1.0.0-M3"
    filters {
        engines {
            include 'junit-jupiter'
            // exclude 'junit-vintage'
        }
        tags {
            // include 'fast', 'smoke'
            // exclude 'slow', 'ci'
        }
        packages {
            // include 'com.sample.included1', 'com.sample.included2'
            // exclude 'com.sample.excluded1', 'com.sample.excluded2'
        }
        //includeClassNamePattern '.*Spec'
        includeClassNamePatterns '.*Test', '.*Tests'
    }
}

Complete build.gradle
This is how your build.gradle file will look like after following the above steps.
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.junit.platform.gradle.plugin'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

buildscript {
	repositories {
        mavenCentral()
    }
    dependencies {
    	// Gradle plugin
        classpath 'org.junit.platform:junit-platform-gradle-plugin:1.0.0-M3'
    }
}

dependencies {
    // download library for JUnit
    compile group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: '5.0.0-M3'
    compile group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: '5.0.0-M3'
    compile group: 'org.junit.platform', name: 'junit-platform-runner', version: '1.0.0-M3'
    
    // compile project for test using Junit Jupiter Api
    testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0-M3")
}

junitPlatform {
    platformVersion "1.0.0-M3"
    filters {
        engines {
            include 'junit-jupiter'
            // exclude 'junit-vintage'
        }
        tags {
            // include 'fast', 'smoke'
            // exclude 'slow', 'ci'
        }
        packages {
            // include 'com.sample.included1', 'com.sample.included2'
            // exclude 'com.sample.excluded1', 'com.sample.excluded2'
        }
        //includeClassNamePattern '.*Spec'
        includeClassNamePatterns '.*Test', '.*Tests'
    }
}

Step 2. Refresh dependencies
Refresh Gradle project so it'll download required libraries.

Step 3. Project structure.
Create test source folder parallel to main source folder (i.e src/test/java and src/test/resources). Follow the image.

JUnit Test + Gradle project structure

Step 4. Create first unit test.

Source code (Addition.java)
package com.javaquery.math;

public class Addition {
	/**
	 * Add given number 'a' and 'b'.
	 * @param a
	 * @param b
	 * @return
	 */
	public int add(int a, int b){
	    return a + b;
	}
}
Source code (AdditionTest.java)
I created two test cases. Out of two case one is success and other is fail.
package com.javaquery.math;

import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import static org.junit.jupiter.api.Assertions.assertEquals;

@RunWith(JUnitPlatform.class)
public class AdditionTest {

	@Test
	public void add(){
	    int x = new Addition().add(12, 3);
	    assertEquals(x, 15);
	}
	
	@Test
	public void failTest(){
	    int y = new Addition().add(20, 30);
	    assertEquals(y, 20);
	}
}

Step 5. Clean and Test
Perform clean and test task on your gradle project.
clean
test

Output
[sts] -----------------------------------------------------
[sts] Starting Gradle build for the following tasks: 
[sts]      clean
[sts]      test
[sts] -----------------------------------------------------
:clean
:compileJava
:processResources UP-TO-DATE
:classes
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:junitPlatformTestJan 01, 2017 11:48:00 PM org.junit.platform.launcher.core.ServiceLoaderTestEngineRegistry loadTestEngines
INFO: Discovered TestEngines with IDs: [junit-jupiter]


Failures (1):
  JUnit Jupiter:AdditionTest:failTest()
    MethodSource [className = 'com.javaquery.math.AdditionTest', methodName = 'failTest', methodParameterTypes = '']
    => org.opentest4j.AssertionFailedError: expected: <50> but was: <20>

Test run finished after 105 ms
[         2 containers found      ]
[         0 containers skipped    ]
[         2 containers started    ]
[         0 containers aborted    ]
[         2 containers successful ]
[         0 containers failed     ]
[         2 tests found           ]
[         0 tests skipped         ]
[         2 tests started         ]
[         0 tests aborted         ]
[         1 tests successful      ]
[         1 tests failed          ]

:junitPlatformTest FAILED

Setup first gradle project in eclipse


Gradle (Modern Open Source Build Tool for Continuous Delivery)
Built over the concepts of Apache Ant and Apache Maven. It helps you with build process of project. Using Gradle you can perform tasks like

  • Build project and its sub projects.
  • Test the build.
  • Execute customized task like you do with any other programming language using.
Gradle uses Groovy Programming language for project configuration.

Step 1. Download Gradle
Download latest binary distribution from https://www.gradle.org/gradle-download/

Step 2. Extract the binary.
Extract the downloaded binary in say C:\gradle-3.2.1.

Step 3. Setup Gradle eclipse preference.
In Eclipse go to Window > Preferences > Gradle (STS) > Folder.


Step 4. Download eclipse gradle plugin.
In Eclipse go to Help > Eclipse Marketplace and search for gradle. There is official eclipse plugin from gradle however I prefer the gradle plugin developed by Spring as a part of Sprint Tool Suits (STS).


Step 5. Create new Gradle project.
Go to File > New > Other > Gradle (STS) > Gradle (STS) Project.


Step 6. Specify your first gradle project name.


Step 7. Upgrade Java version
Sample gradle project is configured to use Java 1.5 so change it to your system's Java version. Open build.gradle and change sourceCompatibility = 1.5 to sourceCompatibility = 1.8

Step 8. Refresh gradle project.

Right click on Project and go to Gradle (STS) > Refresh All.



How to get current working directory path in Java?

Following excerpt show how to get current working directory path in Java using java.nio.file.Path (Java 7 or up).

Source code (CurrentWorkingDirectory.java)
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * Get current working directory path.
 * @author javaQuery
 * @date 27th December, 2016
 * @Github: https://github.com/javaquery/Examples
 */
public class CurrentWorkingDirectory {

    public static void main(String[] args) {
        Path path = Paths.get("");
        String currentWorkingDirectory = path.toAbsolutePath().toString();
        System.out.println("Current working directory: " + currentWorkingDirectory);
    }
}

Output
Current working directory: C:\Users\Vicky\Documents\NetBeansProjects\Examples