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
- Let’s create a database
- Create an user with necessary priviledges
- Flush the priviles for immediate effect
- 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
[text]
#MySQL JDBC Props
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.username=shizune
jdbc.password=tonton
jdbc.url=jdbc:mysql://localhost:3306/family
[/text] - 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
[text]
#MySQL Hibernate Props
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.hbm2ddl.auto=create
[/text] - 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]
<?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>
[/xml] - 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]
<?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>
[/xml]
[bash]
$ mysql -uroot -p
#at the prompt enter your root password
[/bash]
[bash]
mysql> create database family;
Query OK, 1 row affected (0.00 sec)
[/bash]
[bash]
mysql> GRANT ALL PRIVILEGES ON family.* TO ‘shizune’@’localhost’ IDENTIFIED BY ‘tonton’;
Query OK, 0 rows affected (0.05 sec)
[/bash]
[bash]
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
[/bash]
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.
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
[java]
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;
}
}
[/java]
Family Model
[java]
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;
}
}
[/java]
Profile Model
[java]
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;
}
}
[/java]
Let’s create a dummy test class to trigger the generation of our tables in the database
[java]
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);
}
}
[/java]
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
[java]
//private String description; is above
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true,mappedBy="family")
private Set<Person> familyMembers = new HashSet<Person>();
[/java]
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.
[java]
@ManyToOne
@JoinColumn(name = "family_id")
private Family family;
[/java]
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
[java]
// private Family family is above
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "profile")
private Profile profile;
[/java]
Creating Spring-Data-Jpa repositories
FamilyRepository
[java]
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> {
}
[/java]
PersonRepository
[java]
package net.djomeda.tutorials.springdatamvcfamily.repository;
import net.djomeda.tutorials.springdatamvcfamily.model.Person;
import org.springframework.data.jpa.repository.JpaRepository;
[java]
/**
*
* @author joseph
*/
public interface PersonRepository extends JpaRepository<Person, String> {
}
[/java]
ProfileRepository
[java]
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>{
}
[/java]
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