Sunday, January 12, 2014

Liferay Service Builder Many to Many Relation in Plugin Portlet Part-II

Objective:

Implement Many to Many Relation in liferay development using service builder tool.


Implantation in Portlet Development

The following are steps to implement in portlet development
  1. Create simple Liferay MVC portlet using Liferay IDE in eclipse
  2. Create Service.xml file in Portlet WEB-INF directory
  3. Define required entities in service.xml
  4. Define mapping-table attribute for required entity columns
  5. Run Service builder
  6. Use Generated Data base services

Create simple Liferay MVC portlet using Liferay IDE in Eclipse

Firs we need to create simple Liferay MVC portlet using Liferay IDE in eclipse. This is very simple to create in eclipse.

The following is tutorial from setting liferay environment.

Once you set up the development environment then you can create portlet.

Create service.xml file in Portlet WEB-INF directory

Now we need to create service.xml file in portlet WEB-INF directory. This is the configuration file to service builder tool from this it will generate required service to portlet and these service provide database interaction from portlet.

The following screen shows service.xml file in portlet WEB-INF directory



 Define required entities in service.xml

Now we need to defined required entities in service.xml file so that service builder will generate services.

service.xml has defined tags from which we will define entities these tags information available in service builder DTD file.

The following is service builder DTD we can get more information about service builder tags for service.xml


Assume we have two entities Student and Course

The following is service.xml entities configuration


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.1.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_1_0.dtd">
<service-builder package-path="com.meera.db">
<author>E5410</author>
<namespace>meera</namespace>
<entity name="Student" local-service="true" remote-service="true" cache-enabled="false">
<column name="studentId" type="long" primary="true" />
<column name="studentName" type="String" />
<column name="studentPlace" type="String" />

<column name="studentCollege" type="String" />
<column name="courses" type="Collection" entity="Course" mapping-table="Students_Courses"/>
</entity>
<entity name="Course" local-service="true" remote-service="true" cache-enabled="false">
<column name="courseId" type="long" primary="true" />
<column name="courseName" type="String" />
<column name="courseGroup" type="String" />
<column name="students" type="Collection" entity="Student" mapping-table="Students_Courses" />
</entity>
</service-builder>


Define mapping-table attribute for required entity columns

We need to identify the tables which required Many to Many Relation and then we need to define virtual column for each entity and the column should have mapping-table and entity attributes

The following is example for Student and Course Many to Many Relation


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.1.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_1_0.dtd">
<service-builder package-path="com.meera.db">
<author>E5410</author>
<namespace>meera</namespace>
<entity name="Student" local-service="true" remote-service="true" cache-enabled="false">
<column name="studentId" type="long" primary="true" />
<column name="studentName" type="String" />
<column name="studentPlace" type="String" />
<column name="studentCollege" type="String" />
<column name="courses" type="Collection" entity="Course" mapping-table="Students_Courses"/>
</entity>
<entity name="Course" local-service="true" remote-service="true" cache-enabled="false">
<column name="courseId" type="long" primary="true" />
<column name="courseName" type="String" />
<column name="courseGroup" type="String" />
<column name="students" type="Collection" entity="Student" mapping-table="Students_Courses" />
</entity>
</service-builder>


Note:

 We defined two entities in service.xml but service builder will created 3 tables and the third one is mapping tables which map the student and course primary keys.

Run Service builder

Once we complete the configuration now we need run service builder. We can run service builder in eclipse from ant view. We need click on build-service target from ANT view
In normal ant command for run service builder as follows


ant build-service


The following is ANT build-service in eclipse ant view



Once we run service builder then service builder generates all java classes and configuration files along with SQL scripts.

Service builder generate Model/POJO, Service and Util classes. Mostly we will use Util classes to use service to interact with data bases

The following screen shows Generated classes for Portlet



Use Generated Data base services

Once we generated service builder services then we can use in development

We already know we have used Student and Course entities in service.xml so that we will get many service related to these to tables. We will use Util classes to interact with database.

Add Student


Student student=
StudentLocalServiceUtil.createStudent(CounterLocalServiceUtil.increment());
student.setStudentName(studentName);
student.setStudentPlace(studentPlace);
student.setStudentCollege(studentCollege);
student=StudentLocalServiceUtil.addStudent(student);


Add Course


Course course=CourseLocalServiceUtil.createCourse(CounterLocalServiceUtil.increment());
course.setCourseName(courseName);
course.setCourseGroup(courseGroup);
course=CourseLocalServiceUtil.addCourse(course);


Map Multiple course to one student (this is relation mapping)


Long   studentId=2000;
long[] courseIds=[100,101,102]
CourseLocalServiceUtil.addStudentCourses(studentId, courseIds);
                       

Map Multiple Students to one Course (this is relation mapping)


Long   coursetId=2000;
long[] studensIds=[100,101,102]
StudentLocalServiceUtil.addCourseStudents(courseId, studentsIds);
                                    

Get Student Courses & Get Course students

Get Student Courses


List<Course> studentCourseList= CourseLocalServiceUtil.getStudentCourses(studentId);

for(Student curCourse:studentCourseList){

System.out.println(curCourse.getCourseName());

}


Get Course students


List<Student> courseStudentList=StudentLocalServiceUtil.getCourseStudents(courseId);

for(Student curStudent:courseStudentList){

System.out.println(curStudent.getStudentName());

}


Note:

When we use above methods I got class cast exception so i did work around to display student courses and vice versa.

The following is I posted challenge in Liferay forum


The following is work around get each students courses and each course students

Get Student Courses


List studentCoursesList=CourseLocalServiceUtil.getStudentCourses(studentId);

for(int i=0;i<studentCoursesList.size();i++){

Object curCourse=studentCoursesList.get(i);

JSONObject jobj=JSONFactoryUtil.createJSONObject(curCourse.toString());

System.out.println(jobj.getString("courseName"));

}


Get Course Students


List courseStudentList =StudentLocalServiceUtil.getCourseStudents(courseId);

for(int i=0;i<studentCoursesList.size();i++){

Object curStudent= courseStudentList.get(i);

JSONObject jobj=JSONFactoryUtil.createJSONObject(curStudent.toString());

System.out.println(jobj.getString("studentName"));

}



Important Points

  • Liferay have service builder tool from which we can generate service layer for portlet. Service layer is nothing but set of classes and interfaces.
  • Service builder use spring and hibernate to generate service layer for portlet.
  • Service builder need one configuration file called service.xml file in this we will defined required entities for portlet.
  • Liferay service builder support many to many relation. Mapping-table is an attribute for column from which we can achieve many to may relation between tables.
  • Generally service builder generate required SQL scripts for portlet from the entities which are defined in service.xml
  • When we use mapping-key for columns those columns physically not exited in the table but these columns just virtual column to make Many to Many Relation.
  • Service Builder is create all mapping tables which we used values for mapping-key attribute.

Popular Posts

Recent Posts

Recent Posts Widget