In the previous post I created the hibernate mapping files for the Person-Address domain classes. In here we are going to create the hibernate configuration file which creates the database connection according to the defined URL, credentials and other properties.
On the deplyment of the project, the hibernate configuration file is executed through the commands in pom.xml.
We have to put the hibernate configuration file inside the src/main/resources directory. For that right cick on the directory, select new, select other. From there expand the hibernate icon and select Hibernate Configuration file (cfg.xml).
Click Next
Keep the default name "hibernate.cfg.xml" same and click Next
Give the values in the appeared window give the values as follows.
Make sure to verify your mysql username and password, and enter the corret one according to your mysql configuration.
Add the mapping resource entries to your hibernate.cfg.xml file as above.
Here is the directory structureof the project after the hibernate.config.xml file is being added.
Let's add the build elements to the pom.xml file to execute the mapping files and create the tables accordingly.
append the following etries to the pom.xml file inside the project tags.
It is ready to execute the project and one more thing left. Go to mysql command line and create a database called testdb1.
Deploying the project
Right click on the project and goto run as--maven install
In the maven console you can examine the execution. It will display the sql of the tables created. If you have followed the things correctly at the end it will display BUILD SUCCESSFUL.
Inside the target directory hibernate/sql will contain the scema.sql file which is a dump file of the created tables. Also the jar files are created. (testapp-0.0.1-SNAPSHOT.jar and tetsapp-0.0.1-SNAPSHOT-source.jar is created)
The tables can be viewed through mysql command line.
Here the two domain classes have one-to-many relationship. One Person can have many Addresses while one Adress can have only one person. So there is a one-to-many relationship between Person and Address.
In hibernate we have to create the mapping file for each domain class. The mapping file represents the database table which is mapped with the domain class. The table will be created according to things indicated inside mapping classes.
Mapping file for Person.java: - Person.hbm.xml
Mapping file for Address.java: - Address.hbm.xml
Mapping files are located inside src/main/resources. If you have configured Hibernate to be used inside Eclipse you can simply use it. Otherwise let's configure eclpse for hibrenate.
Hibernate-Eclipse Configuration
Download Hibernate tools from here.
Extract the HibernateTools-3.X.zip file and put all the files inside the features folder into the features folder of the eclipse installation directory and put all the files inside the plugins folder into the plugins folder of the ecilpse installation directory. Restart the eclipse.
Right click src/main/resource.
Create New --Package
Create a new package called hibernate.
Then right click on hibernate package and click New--Other
In the New wizard Select Hibernate Icon and expand it.
Select Hibernate XML Mapping file (hbm.xml)
Click Next.
Type Person.hbm.xml as the file name.
Click Next.
In the Hibernate XML mapping file window, click Browse. A window will be opened named Select a class to map.
In the text field type Person.java. And select the correct class from the comming list of classes.
Click Ok and Click Finish
Similarly create the Addrees.hbm.xml file mapped with Address.java class.
Now the project structure will be as follows.
Let's put the content to mapping files. Person.hbm.xml
Let's see the each an ever tag.
class tag: defines which is the class being used and table being mapped for the class.
id tag: An attribute inside class which is going to be primary key of the table (PersonID) name: attribute name of the class
type: type of the table column, to match with the class attribute type (Long=long)
column: column name of the resulting table
property tag All the attributes in the class expect lists and id attribute name: attribute name of the class
type: type of the table column, to match with the class attribute type (String=string)
column: column name of the resulting table
list tag: The lists inside class name: Name of the List inside the class
key tag:Defines the column name of this table which goes as the foriegn key to the Address class
one-to-many tag: This describes the one-to-many relationship which creats the List inside class. (One Project has many Addresses)
class : One-to-many relationship defining class (Address for Person)
Address.hbm.xml
Respond to the Project class set tag with one-to-many tag, here we have to define the many-to-one tag name: name of the attribute of class which reffers the Person class
class: Class with whome this class makes the relationship
This will be added to the ADDRESS table as column name which defined in Person mapping file.(key column="PERSON_ID")
Dependencies are added, so that once the project install goal is being executed the, needed libraries are added to the project. So we can access the spring and hibernate API's inside our project.
Now right click the project. Select Run As and then Select maven install. Or go to project location through command line and execute mvn install command. If no errors were found, and you got BUILD SUCCESSFULL, then you have added the dependencies successfully.
Let's add domain classes to the project. The domain is consist of Person and Address classes.
In maven project directory structure, all the source files will be located in src/main/java directory.
Right click on the src/main/java directory and clike New--Class
Give Person as the class name and org.test.testapp.domain as the package name.
Now create the Address class inside the same package.
Put the following code inside Address.java.
package org.test.testapp.domain;
public class Address { private Long AddressID; private String Street; private String City; private String AreaCode; private Person NewPerson; public Long getAddressID() { return AddressID; }
public void setAddressID(Long addressID) { AddressID = addressID; } public Person getNewPerson() { return NewPerson; }
public void setNewPerson(Person newPerson) { NewPerson = newPerson; }
public String getStreet() { return Street; } public void setStreet(String street) { Street = street; } public String getCity() { return City; } public void setCity(String city) { City = city; } public String getAreaCode() { return AreaCode; } public void setAreaCode(String areaCode) { AreaCode = areaCode; } }
Now put the following code inside Person.java
package org.test.testapp.domain;
import java.util.List;
public class Person { private Long PersonID; private String Name; private String TelNo; private List AddressList; public Long getPersonID() { return PersonID; } public void setPersonID(Long personID) { PersonID = personID; } public String getName() { return Name; } public void setName(String name) { Name = name; } public String getTelNo() { return TelNo; } public void setTelNo(String telNo) { TelNo = telNo; } public List getAddressList() { return AddressList; } public void setAddressList(ListaddressList) { AddressList = addressList; } }
Note: Here the both classes consist of their attributes and the getter setter methods for each attribute. For implemet the hibernate connction to thses classes you must follow this coding standard where attributes kept private and getter setter methods fr each attribute kept public.
Here is the new structural view of the project after adding 2 domain classes.
In the next part let's see how to implement the hibernate mapping classes for these domain classes.
New Wizard will open. There go to maven icon and expand it. Then Select Maven Project item.
Click Next.
In the New Maven Project wizard, select the create a simple project (skip archetype selection) check box.
Click Next
In the New Maven Project wizard enter the following values.
Group Id: org.test.testapp
Artifact Id: testapp
Version: 0.0.1-SNAPSHOT
Packaging: jar
Click Finish.
New Maven Project will be created and display in the Project Explore.
Here is the initial project structure of the created simple Maven project with a jar packaging.
Pom.xml file will contain the following initial details
4.0.0org.test.testapptestapp0.0.1-SNAPSHOT
Run the Project
Executing Maven Goals.
Right Click on the testapp.
Select Run as
Here you can see the configured goals.
Maven install, Maven clean etc
maven install goal will install all the necessary dependancies inside pom.xml and create the packaging file which is jar or war file.
In this project we haven't done anything.
In the next post I will show you haow to create a simple spring-hibernate project.
After we creating the project inside eclipse we can run the application even through command line, if you have installed Apache Maven in to you PC.
For that you have to open commandline and go to the project directory thorugh command line and execute the mvn commands such as mvn clean, mvn install, etc.
Then Select Maven Integration for Eclipse Update Site from the site list and click install
-->
After the successful update the eclipse will be asked for restart. Restart it. Now you can ensure the maven update by opening maven console.
-->
Go to Window icon from the menu bar
Select Show view
Select Console
-->
Eclipse console will be opened. In the console click “Open Console menu”. There you can see maven console selection. Select it. Console will change to maven console.
When multiple threads are accessing a common method through their run methods, the output of that particular program is unpredictable, because while one thread is gone half way through the common method, another thread would gain the common method.
Similarly the common method execution result of multiple threads can have a variety and also may attack to the accuracy of the expected result.
If you need to let the common method accessible by one thread at one time you have to done it through synchronization.
Imagine you expect to increase the value of number in Thread A, and the value of number Thread B by one via calling the common method count().
Examine the following code and see the result by executing it.
class SynchDemo{
int common=7;
public static void main(String args[]){
SynchDemo demo=new SynchDemo();
A a =new A();
a.active(demo);
a.start();
B b=new B();
b.active(demo);
b.start();
}
public int count(int x){
common=x;
try{
Thread.sleep(1000);
}catch(Exception ee){
}
return ++common;
}
}
class A extends Thread{
int number=5;
SynchDemo demo;
public void run(){
System.out.println("Start Thread A\n");
System.out.println("A before increase:"+number+"\n");
System.out.println("A after increase by one:"+demo.count(number)+"\n");
}
public void active(SynchDemo demo){
this.demo=demo;
}
}
class B extends Thread{
int number=10;
SynchDemo demo;
public void run(){
System.out.println("Start Thread B\n");
System.out.println("B before increase:"+number+"\n");
System.out.println("B after increase by one:"+demo.count(number)+"\n");
}
public void active(SynchDemo demo){
this.demo=demo;
}
}
The result can be,
The result of the program is wired, try multiple times.
Increased value of Thread A or Thread B becomes incorrect most of the time.
That's because another thread enters to the method and the value will be updated by that thread. So the previous thread gets the updated value to increase.
Let's use Synchronization....
In Synchronization we can make a code mutually exclusive to multiple threads through a common object. When we add the key word 'synchronized' before the common method, the Thread which calls the method will put a lock to the object it uses to call the method.
Examine the following code and see the result.
class SynchDemo{
int common=7;
public static void main(String args[]){
SynchDemo demo=new SynchDemo();
A a =new A();
a.active(demo);
a.start();
B b=new B();
b.active(demo);
b.start();
}
public synchronized int count(int x){
common=x;
try{
Thread.sleep(1000);
}catch(Exception ee){
}
return ++common;
}
}
class A extends Thread{
int number=5;
SynchDemo demo;
public void run(){
System.out.println("Start Thread A\n");
System.out.println("A before increase:"+number+"\n");
System.out.println("A after increase by one:"+demo.count(number)+"\n");
}
public void active(SynchDemo demo){
this.demo=demo;
}
}
class B extends Thread{
int number=10;
SynchDemo demo;
public void run(){
System.out.println("Start Thread B\n");
System.out.println("B before increase:"+number+"\n");
System.out.println("B after increase by one:"+demo.count(number)+"\n");
}
public void active(SynchDemo demo){
this.demo=demo;
}
}
The result is guranteed to increase the valuse of threads by one.
Here the common method is count(). The object used to call the method is ‘demo’. So the first thread which calls the method count(), gain the lock of the object 'demo'.
As next thread also need 'demo' object to call method count() it has to wait until First thread come out of the synchronized method and release the lock. Soon The next thread can gain the lock in 'demo' and execute count().
The most important thing is, Both methods have used the same object to call the common method. Otherwise synchronizing the method won't help. Try using different objects.
The method join can be used to make one thread joined into the end of another thread.
This is a guranteed method.
Examine the following code and see the result.
class Demo{
public static void main(String args[]){
A a=new A();
B b=new B();
a.start();
b.start();
}
}
class A extends Thread{
public void run(){
System.out.println("Thread A started");
System.out.println("Thread A running");
System.out.println("Thread A ending");
}
}
class B extends Thread{
public void run() {
System.out.println("Thread B started");
System.out.println("Thread B running");
System.out.println("Thread B ending");
}
}
Result can not be guessed, as two threads execute separately.
Imagine you want to execute Thread-B after the complete execution of Thread-A. (First Thread A, then Thread B)
I am goin to show two comman ways to do that.
Method (1)
You can call join method of Thread-A from the Thread-B.
But make sure a thread A need to started, before calling join method.
Then start the Thread B.
class Demo{
public static void main(String args[]){
B b=new B();
b.starting();
}
}
class A extends Thread{
public void run(){
System.out.println("Thread A started");
System.out.println("Thread A running");
System.out.println("Thread A ending");
}
public void starting(){
this.start();
}
}
class B extends Thread{
public void run() {
System.out.println("Thread B started");
System.out.println("Thread B running");
System.out.println("Thread B ending");
}
public void starting(){
A a=new A();
a.starting();
try{
a.join();
}catch(InterruptedException e){
}
this.start();
}
}
Result can be gurantedd to be as follows.
Method (2)
Join thread-A to another third thread , which executes both A, B threads.
Here, Demo class starts A and B threads. Which means main thrad of Demo class.
So first start the Thread A.
Then join main thread or the current into thread thread A.
Start Thread B.
class Demo{
public static void main(String args[]){
A a=new A();
a.start();
try{
a.join();// Joins the main thread of class Demo which is the current thread into Thread A.
//The rest of the code below this point will continue after terminating the Thread A.
}catch(InterruptedException e){
}
System.out.println(a.isAlive());//Thread A is terminated and returns false here
B b=new B();
b.start();
}
}
class A extends Thread{
public void run(){
System.out.println("Thread A started");
System.out.println("Thread A running");
System.out.println("Thread A ending");
}
}
class B extends Thread{
public void run() {
System.out.println("Thread B started");
System.out.println("Thread B running");
System.out.println("Thread B ending");
}
}
Result can be gurantedd to be as follows,.
One important thing to know is that when we call,
a.join();
The current executing thread is joined onto the end of the the thread represented by 'a'.
So the rest of the code beyond this point will execute only after 'a' is teminated (Finished executing its run method).