Saturday, February 23, 2013

Best way to add data to life ray tables.



Best way to add data to life ray tables.
In life ray when we add data to tables we are using service layer add method.
Whenever we use add method it will expect object that going to add in data base.
Example: 
Table Name: XXXXXXX
In service.xml we write like this
<entity name="XXXXXXXX" table="XXXXXXXXX" local-service="true"
                        remote-service="true">
                        <!-- PK fields -->
                        <column name="column1" type="long" primary="true"type="increment" />
                        <!-- Audit fields -->
                        <column name="column2" type="String" />
                        <column name="column3" type="String" />
                        <column name="column4" type="boolean" />
                        <finder name=" column2" return-type=" XXXXXXXX">
                                    <finder-column name="column2" />
                        </finder>
            </entity>


The service builder generated some java classes from that we will add data tables.
Main java classes we uses is
·         XXXXXXXLocalServiceUtil
·         XXXXXXXXServiceUtil
·         XXXXXXUtil
Note: XXXX is any entity name
XXXXXXLocalServiceUtil:
Generally most of the scenarios we use XXX LocalServiceUtil to do CURD operation such as Add, Update and Delete.
If we use this class we won’t get any principle exceptions.


XXXXXXXXServiceUtil:
Whenever we want does some security check then we have to use XXXXServiceUtil java class to do CURD operations.
It having some security checks points so that it wills throw Principle Exception
Example:
When we add role to using RoleServiceUtil from our application then it will throw principle exception.
If login as Admin and run same scenarios it won’t throw any exception.
Because admin have privatization to add user.
So whenever we want perform some kind of permissions check or security check then we have to use this class.
Some time we need to use XXXServiceUtil methods. whenever we get this kind of requirement we have do following
First implement our own custom method in XXXLocalServiceImpl.java when we run service builder custom method syntax automatically created in XXXLocalServiceUtil
Take Example: RoleServiceUtil we have one method
public static com.liferay.portal.model.Role addRole(
                        long companyId, java.lang.String name,
                        java.util.Map<java.util.Locale, java.lang.String> titleMap,
                        java.lang.String description, int type)
                        throws com.liferay.portal.kernel.exception.PortalException,
                                    com.liferay.portal.kernel.exception.


When we call this method in the following way we will get principle exception until we login as admin and use this method.
RoleServiceUtil.addRole(10132,”Student”,null,”this is student”,3);
So first we have to implement custom method in RoleLocalServiceImpl.java from our custom method then we have to use RoleServiceUtil.addRole(….) method in our implementaion.



Public class RoleLocalServiceImpl extends ….{
public static com.liferay.portal.model.Role customeAddRole(
                        long companyId, java.lang.String name,
                        java.util.Map<java.util.Locale, java.lang.String> titleMap,
                        java.lang.String description, int type)
                        throws com.liferay.portal.kernel.exception.PortalException,
                                    com.liferay.portal.kernel.exception{
RoleServiceUtil.addRole(companyId, name, titleMap, description, type);
}}


Once we implement this run service builder then we will this method in RoleLocalServiceUtil class
Now we have call like this
RoleLocalServiceUtil.customAddRole(…..);

Then we won’t get any principle exceptions.
XXXUtil:
All finder methods will be generated in this class.
Like findByName, finByPrimaryKye like this.
But here we need to remember one thing we can’t call this methods directly from XXXXXUtil.
XXXUtil.findByName(..)
When we call directly we will get Exception like Hibernate session bound exception.
We have to implement custom methods in XXXLocalServiceImpl and we have to call from
LocalServiceUtil
RoleLolacServiceImpl extends …{
 Public Role getRoleByName(…){
XXXUtil.findByName(..)
}}

After we have to call like this
RoleLolacServiceUtil.getRoleByName(…..);

Generating Primary Key Value from Counter Service.
Adding Object to data base in Liferay.
Case: 1
Example  Role
Role role=new RoleImpl();
Role.setNeme(“Student”);
Role.setTitle(“Student”)
Role.setDescription(“Stuent”);
Role.setType(1);
RoleLocalServiceUtil.addRole(role);

Observe above scenario we are not set the primary key value to the object so hibernate itself generating primary key and insert into table.
Hera we are setting property increment in service.xml file.
Note: When we run above scenario we need RoleImpl java class in current class path.
Case: 2
We can use method which in XXXServiceUtil
This is not 100% reliable foe when we execute application as guest. That time it will throw principle exception.
RoleServiceUtil.addRole(…….);

The above method throws exception


Assume Following scenarios.

1.      I want insert data in table which in Portal level.
2.      I want insert data from PluginB-Portlet the table in PluginA-Portlet.
I want insert data in table which in Portal level.
For example I want add role to role table.
If I want add role to role table from my plugin portle I need RoleImpl class to create new object. But RoleImpl class not available in Current plugin class path.
Because service layer can share only service classes like XXXUtil,XXXServiceUtil, XXXLocalSericeUtil and interfaces not implementation classes Like XXXServiceImpl, XXXModelImpl, XXXImpl.
If we want use case: 1 we need RoleImpl object but RoleImpl class not available in current class path so we can’t use case 1.
If we want use case: 2 it will throw principle exception if application run as Guest user.
Solution: 1
If we want use Case: 2 we need implement custom method in one of our XXXLocalServiceImpl and from that we have to call XXXLocalServiceUtil.addRole(); but this process also sometimes throws exception.
Solution: 2
We have to load RoleImpl class using Portal class loader and from that can get RoleImpl object. But when I use this process I got exception duplicate primary key exceptions. Here role is not incremented.
Class<?> portalclassObject=PortalClassLoaderUtil.getClassLoader().loadClass("com.liferay.portal.model.impl.RoleImpl");
Role role=(Role)classObject.newInstance();
Role.setNeme(“Student”);
Role.setTitle(“Student”)
Role.setDescription(“Stuent”);
Role.setType(1);
RoleLocalServiceUtil.addRole(role);


I want insert data from PluginB-Portlet but the table in PluginA-Portlet.
Solution: 1
If we want use Case: 2 we need implement custom method in one of our XXXLocalServiceImpl and from that we have to call XXXServiceUtil.addXX(..); but this process also sometimes throws exception.
Solution: 2
We have to load XXXImpl class using Portlet Beans locator class and from that can get XXXImpl object..
This is working between 2 Pluign portlets.
ClassLoader classLoader = (ClassLoader)PortletBeanLocatorUtil.locate(ClpSerializer.SERVLET_CONTEXT_NAME,"portletClassLoader");
Class<?> classObject=classLoader.loadClass("com.vidyayug.global.model.impl.XXXImpl");Role semeObject=(XXX)classObject.newInstance();
semeObject .XXX(“Student”);
semeObject.XXX(“Student”)
semeObject.setXXX(“Stuent”);
semeObject.setXXX(1);
XXXLocalServiceUtil.addXXX(semeObject);


Optimal Solution:
Use Counter LocalServe class to generate Primary key value.
We have Counter table from the table we can generate primary key value based on entity or global counter.
This counter table based on model class it will maintain counter  and each time when create object it will be incremented.
Adding Object to database using Counter increment.
long roleId=CounterLocalServiceUtil.increment();
Role role=RoleLocalServiceUtil.createRole(roleId);
                                    role.setCompanyId(themeDisplay.getCompanyId());
                                    role.setClassNameId(PortalUtil.getClassNameId(Role.class));
                                    role.setClassPK(role.getRoleId());
                                    role.setName(roleName);
                                    role.setDescription(roleName);
                                    role.setTitle(roleName);
                                    role.setType(RoleConstants.TYPE_REGULAR);
                                    role=RoleLocalServiceUtil.addRole(role);

Note: When we observe above code we need not RoleImpl class anywhere.
We just use XXXLocalServiceUtil.create(counterInceremnt); so it will give object after that we can set the data to the object and we can use XXXLocalServiceUtil.addXXX(xxxObject);
We can use counter increment in two ways.
1.      CounterLocalServiceUtil.increment();
2.      CounterLocalServiceUtil.increment(modelClassName);
Example:
Long id=CounterLocalServiceUtil.increment(com.meera.test.Employeee.class);
For more methods you can see CounterLocalServiceUtil java class.

Note: Whenever we are using portal related insertion like user, role, and organization from our plugin portlet please see the increment how they written in liferay means they used global increment or object specific increment. Mostly they may use global increment for portal entity insertions.
CounterLocalServiceUtil.increment();//Global increment
CounterLocalServiceUtil.increment(modelClassName);//entity specific increment

When we use counter increment we need not to use XXXImpl class to create object or we need not load ant XXXImpl class from other class path using either PortalCalssLoader or Portlet Bean locator.
XXXLocalServiceUtil.create(primaryKey) give object and we can set the data to object and we can XXXLocalServiceUtil.addXXx()  to add object to the table.
Note:
If we want use other port let service or portal services service jar file should available in tomcat global class path i.e. tomcat/lib/ext.




Popular Posts

Recent Posts

Recent Posts Widget