setting up domain models with hibernate

Hello,
This is the part 2 of the series about working with maven, spring, and hibernate together. We will use mysql, hibenate,jpa, spring-data-jpa in netbeans.

Before we start, i will like us to be on the same page so , we will create a database for our project, its user and credentials.

  • Let’s connect to mysql database
  • 	
    $ mysql -uroot -p
    #at the prompt enter your root password 
    
  • Let’s create a database
  • mysql> create database family;
    Query OK, 1 row affected (0.00 sec)
    
  • Create an user with necessary priviledges
  • mysql> GRANT ALL PRIVILEGES ON family.* TO 'shizune'@'localhost' IDENTIFIED BY 'tonton';
    Query OK, 0 rows affected (0.05 sec)
    
  • Flush the priviles for immediate effect
  • mysql> FLUSH PRIVILEGES;
    Query OK, 0 rows affected (0.01 sec)
    
    creating database image

    creating database and user

  • Let’s add credential properties file
    • Locate Other Test Sources in projects tab
    • Right Click: src/test/resources > Properties File
    • Name the file: mysql.jdbc.properties
    •                         #MySQL JDBC Props
                               jdbc.driverClassName=com.mysql.jdbc.Driver
                               jdbc.username=shizune
                               jdbc.password=tonton
                               jdbc.url=jdbc:mysql://localhost:3306/family
                               
  • Let’s add hibernate properties file
    • Locate Other Test Sources in projects tab
    • Right Click: src/test/resources > Properties File
    • Name the file: mysql.hibernate.properties
    •                          #MySQL Hibernate Props
                                hibernate.dialect=org.hibernate.dialect.MySQLDialect
                                hibernate.show_sql=true
                                hibernate.format_sql=true
                                hibernate.hbm2ddl.auto=create
                               
  • Notes :

    Because of Netbeans support for certain technologies like persistence or spring, using netbeans way of adding any of these files doesn’t play so well. Apparently Netbeans forces it ways by generating some of files and even adding some dependencies to the classpath regardless of whether is the another version declared in the pom or not. Best way i have found is to create a simple xml file as opposed to use Netbeans.

  • Let’s create our persistence.xml File
    • Right Click: src/main/resources > New Folder
    • name the folder: META-INF
    • Right Click: META-INF > New File > Xml Document
    • Name the document : persistence.xml > Next > choose well-formed document
    • <?xml version="1.0" encoding="UTF-8"?>
      <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
        <persistence-unit name="family" transaction-type="RESOURCE_LOCAL">
          <provider>org.hibernate.ejb.HibernatePersistence</provider>
        </persistence-unit>
      </persistence> 
      
  • Let’s create spring application context
    In this tutorial, we will use spring application context per concern, I mean by that, using an application context for database connectivity only and for nothing else.

    • Right Click: src/test/resources > New Folder
    • name the folder: META-INF
    • Right Click: META-INF > New File > Xml Document
    • Name the document : testing-db-config.xml > Next > choose well-formed document
    • <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:jee="http://www.springframework.org/schema/jee"
             xmlns:lang="http://www.springframework.org/schema/lang"
             xmlns:util="http://www.springframework.org/schema/util"
             xmlns:p="http://www.springframework.org/schema/p" 
             xmlns:jpa="http://www.springframework.org/schema/data/jpa"
             xmlns:context="http://www.springframework.org/schema/context"
             xsi:schemaLocation="http://www.springframework.org/schema/beans 
             http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/jee 
             http://www.springframework.org/schema/jee/spring-jee-3.1.xsd http://www.springframework.org/schema/lang 
             http://www.springframework.org/schema/lang/spring-lang-3.1.xsd http://www.springframework.org/schema/util 
             http://www.springframework.org/schema/util/spring-util-3.1.xsd http://www.springframework.org/schema/context 
             http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/data/jpa  http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd 
             http://www.springframework.org/schema/tx">
           <bean id="propertyConfigurer"
                class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
              <property name="locations">
                  <list>
                      <value>classpath:mysql.hibernate.properties</value>
                      <value>classpath:mysql.jdbc.properties</value>
                  </list>
              </property>
          </bean>     
          
          <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
              <property name="driverClassName" value="${jdbc.driverClassName}" />
              <property name="url" value="${jdbc.url}" />
              <property name="username" value="${jdbc.username}"/>
              <property name="password" value="${jdbc.password}" />
          </bean>
          
          <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
              <property name="dataSource" ref="dataSource" />
              <property name="packagesToScan" value="net.djomeda.tutorials.springdatamvcfamily.model"/>
              <property name="persistenceUnitName" value="family" />
              <property name="jpaProperties">
                  <props>
                      <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                      <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                      <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                      <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                  </props>
              </property>
          </bean>
          <bean id="jpdDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
          <jpa:repositories base-package="net.djomeda.tuturialsspringdatamvcfamily.repository"/>
          
      </beans>
       

Creating Models
For now we will create Family, Person and Profile models without any relationship between them and then build the relations bit by bit. We will create them in net.djomeda.tutorials.springdatamvcfamily.model package.

Person Model

package net.djomeda.tutorials.springdatamvcfamily.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 *
 * @author joseph
 */
@Entity
@Table(name = "person")
public class Person {
    
    @Id
    @Column(name = "person_id")
    private String ID;
    
    @Column(name = "name")
    private String name;
    
    @Column(name = "age")
    private String age;
    
    @Column(name = "gender")
    private String gender;

    /**
     * @return the ID
     */
    public String getID() {
        return ID;
    }

    /**
     * @param ID the ID to set
     */
    public void setID(String ID) {
        this.ID = ID;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the age
     */
    public String getAge() {
        return age;
    }

    /**
     * @param age the age to set
     */
    public void setAge(String age) {
        this.age = age;
    }

    /**
     * @return the gender
     */
    public String getGender() {
        return gender;
    }

    /**
     * @param gender the gender to set
     */
    public void setGender(String gender) {
        this.gender = gender;
    } 
}

Family Model

package net.djomeda.tutorials.springdatamvcfamily.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 *
 * @author joseph
 */
@Entity
@Table(name = "family")
public class Family {
    @Id
    @Column(name = "family_id")
    private String ID;
    
    @Column(name = "name")
    private String name;
    
    @Column(name = "tribe")
    private String tribe;
    
    @Column(name = "description")
    private String description;

    /**
     * @return the ID
     */
    public String getID() {
        return ID;
    }

    /**
     * @param ID the ID to set
     */
    public void setID(String ID) {
        this.ID = ID;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the tribe
     */
    public String getTribe() {
        return tribe;
    }

    /**
     * @param tribe the tribe to set
     */
    public void setTribe(String tribe) {
        this.tribe = tribe;
    }

    /**
     * @return the description
     */
    public String getDescription() {
        return description;
    }

    /**
     * @param description the description to set
     */
    public void setDescription(String description) {
        this.description = description;
    }
    
    
    
}

Profile Model

package net.djomeda.tutorials.springdatamvcfamily.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

/**
 *
 * @author joseph
 */
@Entity
@Table(name = "profile")
public class Profile {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int ID;
    @Column(name = "favorite_hobby")
    private String favoriteHobby;
    
    @Column(name = "averageGradeInSchool")
    private String averageGradeInSchool; 

    /**
     * @return the ID
     */
    public int getID() {
        return ID;
    }

    /**
     * @param ID the ID to set
     */
    public void setID(int ID) {
        this.ID = ID;
    }

    /**
     * @return the favoriteHobby
     */
    public String getFavoriteHobby() {
        return favoriteHobby;
    }

    /**
     * @param favoriteHobby the favoriteHobby to set
     */
    public void setFavoriteHobby(String favoriteHobby) {
        this.favoriteHobby = favoriteHobby;
    }

    /**
     * @return the averageGradeInSchool
     */
    public String getAverageGradeInSchool() {
        return averageGradeInSchool;
    }

    /**
     * @param averageGradeInSchool the averageGradeInSchool to set
     */
    public void setAverageGradeInSchool(String averageGradeInSchool) {
        this.averageGradeInSchool = averageGradeInSchool;
    }
            
}

Let’s create a dummy test class to trigger the generation of our tables in the database

  • Right Click: Family > tools > Create Tests
  • Class Name: net.djomeda.tutorials.springdatamvcfamily.model.FamilyTest
  • package net.djomeda.tutorials.springdatamvcfamily.model;
    
    import org.junit.Assert;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    /**
     *
     * @author joseph
     */
    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("classpath:META-INF/testing-db-config.xml")
    public class FamilyTest {
        
        public FamilyTest() {
        }
        
      @Test
      public void GenerateDatabaseTest(){
          Assert.assertTrue(true);
      }
    }
    
  • Right Click inside the file > Test File
  • If all the files and configurations are done properly the test will succeed and thus generating 3 Tables in the database.

    Mapping Models Relationships

    Linking Family to Person in a OneToMany relationsship

  • Append the following to Family.java properties to enable a unidirectional OneToMany relationship
  •                //private String description; is above
                  
                  @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true,mappedBy="family")
                  private Set<Person> familyMembers = new HashSet<Person>();
            

    Linking Person to Family making the ManyToOne side of the relationship. Now because Person object knows about Family our relationship becomes bi-directional. Append the following to Person.java class after gender property.

        @ManyToOne
        @JoinColumn(name = "family_id")
        private Family family;
    

    Linking Person to Profile in a OneToOne relationship. This is an example of unidirectional relationship where Profile object doesn’t know about its owner Person class

  • Append the following to Person.java
  •        // private Family family is above
           @OneToOne(cascade = CascadeType.ALL)
           @JoinColumn(name = "profile")
           private Profile profile;
    

    Creating Spring-Data-Jpa repositories

    FamilyRepository

  • Right Click: net.djomeda.tutorial.springdatamvcfamily.repository > New > Other
  • Categories: Java > File Types: Java Interface > Next
  • Class Name: FamilyRepository > Finish
  •           package net.djomeda.tutorials.springdatamvcfamily.repository;
    
    import net.djomeda.tutorials.springdatamvcfamily.model.Family;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    /**
     *
     * @author joseph
     */
    public interface FamilyRepository extends JpaRepository<Family, String> {
        
    }
    

    PersonRepository

  • Right Click: net.djomeda.tutorial.springdatamvcfamily.repository > New > Java Interface
  • Class Name: PersonRepository > Finish
  •            package net.djomeda.tutorials.springdatamvcfamily.repository;
    
    import net.djomeda.tutorials.springdatamvcfamily.model.Person;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    /**
     *
     * @author joseph
     */
    public interface PersonRepository extends JpaRepository<Person, String> {
        
    }
    
    

    ProfileRepository

  • Right Click: net.djomeda.tutorial.springdatamvcfamily.repository > New > Java Interface
  • Class Name: ProfileRepository > Finish
  • package net.djomeda.tutorials.springdatamvcfamily.repository;
    
    import net.djomeda.tutorials.springdatamvcfamily.model.Profile;
    import org.springframework.data.jpa.repository.JpaRepository;
    
    /**
     *
     * @author joseph
     */
    public interface ProfileRepository extends JpaRepository<Profile, Integer>{
        
    }
    
    

    Voila! we have a very capable data layer set with spring-data-jpa. Next we will see how to use it in a web application the MVC controllers and views

    Leave a Comment

    Your email address will not be published. Required fields are marked *

    captcha * Time limit is exhausted. Please reload the CAPTCHA.

    This site uses Akismet to reduce spam. Learn how your comment data is processed.