text
cyber space for sharing the day to day technology related learning and working experiences with interested parties. http://www.chathurangaonline.com
Showing posts with label JPA 2. Show all posts
Showing posts with label JPA 2. Show all posts
Saturday, September 7, 2013
Hibernate Relationship Mapping with Compound Primary Key
Wednesday, September 4, 2013
How to create compound primary key in hibernate with @IdClass Annotation
text
Tuesday, September 3, 2013
How to create compound primary key in hibernate with @EmbeddedId Annotation
text
Sunday, September 1, 2013
How to create compound primary key in hibernate with @Embeddable Annotation
text
Friday, August 30, 2013
Compound Primary Keys in Hibernate using Annotations
most of the cases, identifier (primary key) of the entity will be a single attribute. but there will be some cases where the primary key of the entity will be comprised by several attributes. In other words, primary key will consist of more than one column. if the primary key consist of more than one attribute/column, we called it as composite primary key or compound primary key.
In hibernate, there are three ways that can be used to create compound primary key in a entity class using annotations. In all of these three scenarios, it will be required to create a separate class for the compound primary key.
1. Compound primary key with @Embeddable annotation
mark the compound primary key (PK) class with @Embeddable annotation and add the instance of the PK class to the entity class as a normal property. then mark it with @Id annotation as usual.
2. Compound Primary key with @EmbeddableId annotation
create the compound PK class as POJO (Plain Old Java Object) and add it as a normal property for the Entity class. then mark that instance with @EmbeddableId annotation.
3. Compound Primary key with @IdClass annotation
declare the compound primary key class with @IdClass annotation and add the all primary key properties of that class to the entity class as normal properties. then mark all the added primary key properties with @Id annotation.
Hope this will be helpful for you!
Cheers
Chathuranga Tennakoon
www.chathurangaonline.com
In hibernate, there are three ways that can be used to create compound primary key in a entity class using annotations. In all of these three scenarios, it will be required to create a separate class for the compound primary key.
1. Compound primary key with @Embeddable annotation
mark the compound primary key (PK) class with @Embeddable annotation and add the instance of the PK class to the entity class as a normal property. then mark it with @Id annotation as usual.
2. Compound Primary key with @EmbeddableId annotation
create the compound PK class as POJO (Plain Old Java Object) and add it as a normal property for the Entity class. then mark that instance with @EmbeddableId annotation.
3. Compound Primary key with @IdClass annotation
declare the compound primary key class with @IdClass annotation and add the all primary key properties of that class to the entity class as normal properties. then mark all the added primary key properties with @Id annotation.
Hope this will be helpful for you!
Cheers
Chathuranga Tennakoon
www.chathurangaonline.com
Tuesday, August 20, 2013
Hibernate 4 - One to Many mapping with Annotations (LAZY loading example)
the technologies i ma using for this example.
Hibernate 4
testNG for TDD
MySQL
Maven
In this example, we are going to use our Lecturer and Course example again the entity relationship will be decided based on the following assumption.
Assumption:
Lecturer can teach many number of courses.
Therefore the relationship between two entities can be described as follows.
Lecturer.java
Course.java
i have used the following code to check the mapping relationship and the lazy loading.
when i run the above code, i got the following output and seems to be that the lazy loading is also working fine.
you can get the example source code from following gitHub repository.
Get SourceCode from GitHub
Hope this will be helpful for you!
Cheers
Chathuranga Tennakoon
chathuranga.t@gmail.com
www.chathurangaonline.com
Hibernate 4
testNG for TDD
MySQL
Maven
In this example, we are going to use our Lecturer and Course example again the entity relationship will be decided based on the following assumption.
Assumption:
Lecturer can teach many number of courses.
Therefore the relationship between two entities can be described as follows.
- relationship from Lecturer to Course is One-To-Many (lecturer can teach many number of courses)
- relationship from Course to Lecturer is Many-To-One (many courses will be taught by one lecturer)
Lecturer.java
package com.chathurangaonline.examples.model; import javax.persistence.*; import java.io.Serializable; import java.util.List; @Entity @Table(name = "Lecturer") public class Lecturer implements Serializable{ @Id @GeneratedValue @Column(name = "id") private Long id; @OneToMany(fetch = FetchType.LAZY,cascade = CascadeType.ALL,mappedBy = "lecturer") private ListcourseList; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public List getCourseList() { return courseList; } public void setCourseList(List courseList) { this.courseList = courseList; } }
Course.java
package com.chathurangaonline.examples.model; import javax.persistence.*; import java.io.Serializable; @Entity @Table(name = "Course") public class Course implements Serializable{ @Id @GeneratedValue @Column(name = "id") private Long id; @Column(name = "course_name") private String courseName; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "lecturer_id") private Lecturer lecturer; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getCourseName() { return courseName; } public void setCourseName(String courseName) { this.courseName = courseName; } public Lecturer getLecturer() { return lecturer; } public void setLecturer(Lecturer lecturer) { this.lecturer = lecturer; } }
i have used the following code to check the mapping relationship and the lazy loading.
@Test public void testSave() throws Exception { //saving the lecturer Lecturer lecturer = new Lecturer(); lecturerDao.save(lecturer); Assert.assertNotNull(lecturer.getId()); //saving the course Course course = new Course(); course.setCourseName("Java"); course.setLecturer(lecturer); courseDao.save(course); Assert.assertNotNull(course.getId()); System.out.println(" retrieving the lecturer record with id ["+lecturer.getId()+"]"); Lecturer lecturer2 = lecturerDao.findById(lecturer.getId()); System.out.println("lecturer found with id ["+lecturer2.getId()+"] retrieved"); System.out.println("course retrieving ......."); ListcourseList1 = lecturer2.getCourseList(); System.out.println(" course list retrieved ["+courseList1.size()+"]"); }
when i run the above code, i got the following output and seems to be that the lazy loading is also working fine.
you can get the example source code from following gitHub repository.
Get SourceCode from GitHub
Hope this will be helpful for you!
Cheers
Chathuranga Tennakoon
chathuranga.t@gmail.com
www.chathurangaonline.com
Monday, August 12, 2013
Lazy loading not wotking with hibernate OneToOne mapping
in my experience, i have encountered an issue that the hibernate lazy loading is not working when we map the relationship between two entities using OneToOne annotations.see the following examples.
Lecturer.java
Course.java
you will notice that the mapping from the lecturer to course is One-To-One and the fetch type is LAZY. Since the fetch type is LAZY, the associated course object should not be loaded when the lecturer object is loaded. the associated course object should be loaded only when the user request it. that is the behavior of the lazy fetch mode.
but in this example, you will notice that course object is loaded (EAGER resolved) when the time that the lecturer object is loaded regardless of the LAZY fetch type. it always eagerly resolve the associated entities even if it is declared as LAZY fetch. . please refer the below screenshot.
you will see that when retrieving the Lecturer object with given id, it generates and issue a SQL query to retrieve data from the database. when the lecturer object is retrieved, it loads and populates the associated course object also. that is why when we request the course object and its attributes, it directly give the values of the attributes without issuing another SQL query. the reason for this EAGER behavior can be described as follows.
you will notice that the OneToOne relationship is not mandatory and it is optional.(by default, the optional=true). since the relationship is optional, hibernate(ORM framework) does not know whether the given lecturer teach a course or not without issuing an another query. therefore hibernate cannot populate the course reference with a proxy, because it does not know whether a course exists for that lecturer. On the other hand, it cannot populate the course attribute with null because, there may be lecturers who teach courses. therefore hibernate performs the EAGER loading regardless of the LAZY fetch mode if the relationship is OneToOne and it is optional.
to overcome to above issue and make the LAZY loading working, you need to make the relationship as mandatory. In oder to do that, set the optional=false.
then the lazy loading should works as usual.
refer the following screenshot and identify how the lazy loading works. refer the below screenshot.
you will see that when retrieving the associated course instance from the lecturer instance, it generates another SQL queries to retrieve the course details associated. this is because the Fetch type of the relationship is LAZY.
references :
http://stackoverflow.com/questions/17987638/hibernate-one-to-one-lazy-loading-optional-false
Hope this will be helpful for you!
Thanks
Chathuranga Tennakoon
chathuranga.t@gmail.com
www.chathurangaonline.com
Lecturer.java
package com.chathurangaonline.examples.model; import javax.persistence.*; import java.io.Serializable; @Entity @Table(name = "Lecturer") public class Lecturer implements Serializable{ @Id @GeneratedValue @Column(name = "id") private Long id; @OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL) @JoinColumn(name = "course_id") private Course course; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Course getCourse() { return course; } public void setCourse(Course course) { this.course = course; } }
Course.java
package com.chathurangaonline.examples.model; import javax.persistence.*; import java.io.Serializable; @Entity @Table(name = "Course") public class Course implements Serializable{ @Id @GeneratedValue @Column(name = "id") private Long id; @Column(name = "course_name") private String courseName; @OneToOne(fetch = FetchType.LAZY,mappedBy = "course") private Lecturer lecturer; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getCourseName() { return courseName; } public void setCourseName(String courseName) { this.courseName = courseName; } public Lecturer getLecturer() { return lecturer; } public void setLecturer(Lecturer lecturer) { this.lecturer = lecturer; } }
you will notice that the mapping from the lecturer to course is One-To-One and the fetch type is LAZY. Since the fetch type is LAZY, the associated course object should not be loaded when the lecturer object is loaded. the associated course object should be loaded only when the user request it. that is the behavior of the lazy fetch mode.
but in this example, you will notice that course object is loaded (EAGER resolved) when the time that the lecturer object is loaded regardless of the LAZY fetch type. it always eagerly resolve the associated entities even if it is declared as LAZY fetch. . please refer the below screenshot.
you will see that when retrieving the Lecturer object with given id, it generates and issue a SQL query to retrieve data from the database. when the lecturer object is retrieved, it loads and populates the associated course object also. that is why when we request the course object and its attributes, it directly give the values of the attributes without issuing another SQL query. the reason for this EAGER behavior can be described as follows.
@OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL) @JoinColumn(name = "course_id") private Course course;
you will notice that the OneToOne relationship is not mandatory and it is optional.(by default, the optional=true). since the relationship is optional, hibernate(ORM framework) does not know whether the given lecturer teach a course or not without issuing an another query. therefore hibernate cannot populate the course reference with a proxy, because it does not know whether a course exists for that lecturer. On the other hand, it cannot populate the course attribute with null because, there may be lecturers who teach courses. therefore hibernate performs the EAGER loading regardless of the LAZY fetch mode if the relationship is OneToOne and it is optional.
to overcome to above issue and make the LAZY loading working, you need to make the relationship as mandatory. In oder to do that, set the optional=false.
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, optional = false) @JoinColumn(name = "course_id") private Course course;
then the lazy loading should works as usual.
refer the following screenshot and identify how the lazy loading works. refer the below screenshot.
you will see that when retrieving the associated course instance from the lecturer instance, it generates another SQL queries to retrieve the course details associated. this is because the Fetch type of the relationship is LAZY.
references :
http://stackoverflow.com/questions/17987638/hibernate-one-to-one-lazy-loading-optional-false
Hope this will be helpful for you!
Thanks
Chathuranga Tennakoon
chathuranga.t@gmail.com
www.chathurangaonline.com
Tuesday, August 6, 2013
XML based mapping VS Annotation based mapping in hibernate
There are two ways that we can perform entity mapping in hibernate.
1. XML based mapping
2. Annotation based mapping.
the intention of this article is to select the appropriate mapping option for your project. by the way, i always prefer the annotation based mapping for my projects because of the following reasons.
i personally prefer the annotation based mapping because of the following reasons.
The decision of selecting the appropriate mapping option (either Annotation based or XML based) for your project should be done wisely.
when to use XML based mapping
it is safer to use XML based mapping to integrate/use the hibernate for a project that is already developed. since you are using XML based mapping, you do not have to touch or modify the POJO classes that are already developed and stable. if you are confident enough to modify the POJOs, then you may use annotation based mapping.(But not recommended)
Another scenario where we can use the XML based mapping is that, we are getting a request to integrate/use the hibernate for a project that is already developed. but the problem is we do not have the source code of the POJO classes. at that time, we cannot use the annotation to map the entities because, we do not have the source code of POJOs. in such case, we have to use the XML based mapping.
when to use the Annotation based mapping
XML based mapping is a proprietary format of Hibernate ORM framework.
if you intend to expose your applications to other JPA2 compliant other ORM frameworks, you must use the Annotation based mapping. but keep it in mid that there are two types of annotations.
Hope this will be helpful for you!
Cheers
Chathuranga Tennakoon
www.chathurangaonline.com
1. XML based mapping
2. Annotation based mapping.
the intention of this article is to select the appropriate mapping option for your project. by the way, i always prefer the annotation based mapping for my projects because of the following reasons.
- i personally hate a load of XML mapping files and it adds unnecessary complexity for the project.
- it degrade the readability and understandability of the code because your POJO (Plain Old Java Objects) is independent from the relevant XML mapping files. therefore you cannot understand the database constraints, associations and mapping relationships between entities just looking at only the POJOs. you need an additional effort to read the XML mapping files and POJOs simultaneously to get an understanding of how entity mapping has been done.
i personally prefer the annotation based mapping because of the following reasons.
- it is very simple to perform entity mapping with annotations and i don't have to maintain separate XML configuration files.
- In Annotation mapping,the entity relationships, mappings and other DB constraints are also defined in the POJO along with the relevant attribute. therefore it improves the understandability and the readability of the code.
The decision of selecting the appropriate mapping option (either Annotation based or XML based) for your project should be done wisely.
when to use XML based mapping
it is safer to use XML based mapping to integrate/use the hibernate for a project that is already developed. since you are using XML based mapping, you do not have to touch or modify the POJO classes that are already developed and stable. if you are confident enough to modify the POJOs, then you may use annotation based mapping.(But not recommended)
Another scenario where we can use the XML based mapping is that, we are getting a request to integrate/use the hibernate for a project that is already developed. but the problem is we do not have the source code of the POJO classes. at that time, we cannot use the annotation to map the entities because, we do not have the source code of POJOs. in such case, we have to use the XML based mapping.
when to use the Annotation based mapping
XML based mapping is a proprietary format of Hibernate ORM framework.
if you intend to expose your applications to other JPA2 compliant other ORM frameworks, you must use the Annotation based mapping. but keep it in mid that there are two types of annotations.
- Annotations in the javax.persistance package
- Annotations in the org.hibernate package
Hope this will be helpful for you!
Cheers
Chathuranga Tennakoon
www.chathurangaonline.com
Wednesday, July 17, 2013
Difference between Unidirectional and Bidirectional mapping in hibernate
Unidirectional Mapping
When only one of the pair of entities contains a reference to the other, the association is unidirectional. for example, assume that there are two entities called Lecturer and Course.
In unidirectional mapping, the lecturer will hold a reference for the course OR course will hold a reference for the lecturer.(Not Both) It is mandatory that the references should not be mapped to the both directions and there should be only one direction(unidirectional) mapping.
In unidirectional mapping, it will provide the navigational access only to one direction.
eg:-
assumption: lecturer can teach only once course and a given course can be taught only by one lecturer
unidirectional mapping from lecturer to course
class Lecturer{
private Long id;
private String lecturerName;
private Course;
//getter and setters
}
class Course{
private Long id;
private String courseName;
//getter and setters
}
unidirectional mapping from course to lecturer
class Lecturer{
private Long id;
private String lecturerName;
//getter and setters
}
class Course{
private Long id;
private String courseName;
private Lecturer lecturer;
//getter and setters
}
Bidirectional Mapping
if the association between both entities are mutual, then it is known as bidirectional mapping. in bidirectional mapping, the lecturer should hold to a reference for the course and the same time the course should a reference to the lecturer.
therefore in bi-directional mapping, it will provide the navigational access to the both directions.
eg:-
assumption: lecturer can teach only once course and a given course can be taught only by one lecturer
class Lecturer{
private Long id;
private String lecturerName;
private Course;
//getter and setters
}
class Course{
private Long id;
private String courseName;
private Lecturer lecturer;
//getter and setters
}
hope this will help for you!
Cheers
Chathuranga Tennakoon
www.chathurangaonline.com
Tuesday, February 21, 2012
Hibernate Vs JPA
i found a very good article that describes about JPA vs Hibernate. i decided to re-post that article in my blog for to improve the availability of the article. (even if the original source is not available, you can refer the article through my blog.)
source :- http://www.differencebetween.com/difference-between-jpa-and-vs-hibernate/
Thanks and Credits should go to the Original Author who compose this valuable article.
cheers!!!
Chathuranga Tennakoon
chathuranga.t@gmail.com
JPA vs Hibernate
Almost all of enterprise applications are required to access relational databases regularly. But a problem faced with earlier technologies (such as JDBC) was the impedance mismatch (difference between object-oriented and relational technologies). A solution for this problem was introduced through the introduction of an abstract layer called Persistence layer, which encapsulates database access from the business logic. JPA (Java Persistence API) is a framework dedicated for the management of relational data (using the persistence layer) in Java applications. There are many vendor implementations of JPA used within the Java developer community. Hibernate is the most popular such implementation of JPA (DataNucleus, EclipseLink and OpenJPA are some others). The newest JPA version (JPA 2.0) is fully supported by Hibernate 3.5, which was released in March, 2010.
What is JPA?
JPA is a framework for managing relational data for Java. It can be used with applications utilizing JSE (Java Platform, Standard Edition) or JEE (Java Platform, Enterprise Edition). Its current version is JPA 2.0, which was released on 10 Dec, 2009. JPA replaced EJB 2.0 and EJB 1.1 entity beans (which were heavily criticized for being heavyweight by the Java developer community). Although entity beans (in EJB) provided persistence objects, many developers were used to utilizing relatively lightweight objects offered by DAO (Data Access Objects) and other similar frameworks instead. As a result, JPA was introduced, and it captured many of the neat features of the frameworks mentioned above.
Persistence as described in JPA covers the API (defined in javax.persistence), JPQL (Java Platform, Enterprise Edition) and metadata required for relational objects. State of a persistence entity is typically persisted in to a table. Instances of an entity correspond to rows of the table of the relational database. Metadata is used to express the relationships between entities. Annotations or separate XML descriptor files (deployed with the application) are used to specify metadata in entity classes. JPQL, which is similar to SQL queries, are used to query stored entities.
What is Hibernate?
Hibernate is a framework that can be used for object-relational mapping intended for Java programming language. More specifically, it is an ORM (object-relational mapping) library that can be used to map object-relational model in to conventional relational model. In simple terms, it creates a mapping between Java classes and tables in relational databases, also between Java to SQL data types. Hibernate can also be used for data querying and retrieving by generating SQL calls. Therefore, the programmer is relieved from the manual handling of result sets and converting objects. Hibernate is released as a free and open source framework distributed under GNU license. An implementation for JPA API is provided in Hibernate 3.2 and later versions. Gavin King is the founder of Hibernate.
What is the difference between JPA and Hibernate?
JPA is a framework for managing relational data in Java applications, while Hibernate is a specific implementation of JPA (so ideally, JPA and Hibernate cannot be directly compared). In other words, Hibernate is one of the most popular frameworks that implements JPA. Hibernate implements JPA through Hibernate Annotation and EntityManager libraries that are implemented on top of Hibernate Core libraries. Both EntityManager and Annotations follow the lifecycle of Hibernate. The newest JPA version (JPA 2.0) is fully supported by Hibernate 3.5. JPA has the benefit of having an interface that is standardized, so the developer community will be more familiar with it than Hibernate. On the other hand, native Hibernate APIs can be considered more powerful because its features are a superset of that of JPA.
Thanks and Credits should go to the Original Author who compose this valuable article.
cheers!!!
Chathuranga Tennakoon
chathuranga.t@gmail.com
Friday, February 17, 2012
Many to Many mapping in JPA annotations
ER diagram
------
Student.java
Course.java
@JoinTable annotation is declared in the POJO class that owns the relationship. since this is many to many relationship, both class own the relationship. therefore @JoinTable annoatation is declared in the both classes. (therefore referential integrity constraint will be accurately maintained)
hope this will helpful for you!
------
Student.java
package org.convey.user.registration.model; import javax.persistence.*; import java.util.List; /** * Name: Chathuranga Tennakoon * Mobile: 0094759610139 * Blog: chathurangat.blogspot.com * Email: chathuranga.t@gmail.com */ @Entity @Table(name="student") public class Student { @Id @GeneratedValue @Column(name = "student_id") private int studentId; @Column(name="student_name") private String studentName; @Column(name="student_address") private String studentAddress; @Column(name="version") private long version; @ManyToMany @JoinTable( name="student_course", joinColumns = {@JoinColumn(name = "studentID",referencedColumnName = "student_id")}, inverseJoinColumns = {@JoinColumn(name = "courseID", referencedColumnName = "course_id")}) private Listcourses; public int getStudentId() { return studentId; } public void setStudentId(int studentId) { this.studentId = studentId; } public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public String getStudentAddress() { return studentAddress; } public void setStudentAddress(String studentAddress) { this.studentAddress = studentAddress; } public long getVersion() { return version; } public void setVersion(long version) { this.version = version; } public List getCourses() { return courses; } public void setCourses(List courses) { this.courses = courses; } }
Course.java
package org.convey.user.registration.model; import javax.persistence.*; import java.util.List; /** * Name: Chathuranga Tennakoon * Mobile: 0094759610139 * Blog: chathurangat.blogspot.com * Email: chathuranga.t@gmail.com */ @Entity @Table(name="course") public class Course { @Id @GeneratedValue @Column(name="course_id") private int courseId; @Column(name="course_name") private String courseName; @Column(name="course_description") private String courseDescription; @Column(name="version") private long version; @ManyToMany @JoinTable( name="student_course", joinColumns = {@JoinColumn(name = "courseID",referencedColumnName = "course_id")}, inverseJoinColumns = {@JoinColumn(name = "studentID", referencedColumnName = "student_id")}) private List<Student> students; public int getCourseId() { return courseId; } public void setCourseId(int courseId) { this.courseId = courseId; } public String getCourseName() { return courseName; } public void setCourseName(String courseName) { this.courseName = courseName; } public String getCourseDescription() { return courseDescription; } public void setCourseDescription(String courseDescription) { this.courseDescription = courseDescription; } public long getVersion() { return version; } public void setVersion(long version) { this.version = version; } public List<Student> getStudents() { return students; } public void setStudents(List<Student> students) { this.students = students; } }//course
- Student can register for many courses.
- A given course has many registered students
@JoinTable annotation is declared in the POJO class that owns the relationship. since this is many to many relationship, both class own the relationship. therefore @JoinTable annoatation is declared in the both classes. (therefore referential integrity constraint will be accurately maintained)
hope this will helpful for you!
Thursday, February 16, 2012
persist() vs merge() in Hibernate JPA
http://blog.xebia.com/2009/03/23/jpa-implementation-patterns-saving-detached-entities/
http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge
http://stackoverflow.com/questions/1069992/jpa-entitymanager-why-use-persist-over-merge
Subscribe to:
Posts (Atom)