Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Gnaniyar Zubair
Composite Key Issue
April 11, 2013 4:21 AM
Answer

Gnaniyar Zubair

Rank: Liferay Master

Posts: 601

Join Date: December 19, 2007

Recent Posts

When i try to persiste the data into composite key table, it throws Cannot Cast Exception like this :

com.test.service.persistence.TestPK cannot be cast to com.test.service.persistence.TestPK


Am i missed something ? Here is my code:


TestPK testPK = new TestPK();
testPK .setFirstKey(firstKey);
testPK .setSecondKey(secondKey);

Test test = TestLocalServiceUtil.createTest(testPK );

TestLocalServiceUtil.updateTest(test );



Even composite keys table is not auto generated. Is there any issue in Liferay 6.1.X for generating and persisting the data of composite Keys in Service Builder?

- Gnaniyar Zubair
Juan Gonzalez
RE: Composite Key Issue
April 11, 2013 3:49 AM
Answer

Juan Gonzalez

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1841

Join Date: October 28, 2008

Recent Posts

Do you have your portlet service jar in both server classpath and portlet WAR?
Gnaniyar Zubair
RE: Composite Key Issue
April 11, 2013 4:23 AM
Answer

Gnaniyar Zubair

Rank: Liferay Master

Posts: 601

Join Date: December 19, 2007

Recent Posts

I am using global service inside tomcat/ext/lib .
Juan Gonzalez
RE: Composite Key Issue
April 11, 2013 4:26 AM
Answer

Juan Gonzalez

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1841

Join Date: October 28, 2008

Recent Posts

Is that service jar inside your portlet WEB-INF/lib? In that case, try removing it and redeploy.
Gnaniyar Zubair
RE: Composite Key Issue
April 11, 2013 5:23 AM
Answer

Gnaniyar Zubair

Rank: Liferay Master

Posts: 601

Join Date: December 19, 2007

Recent Posts

emoticon From that location only, i can copy and place it in global location.

It is available in both location.

- Gnaniyar Zubair
David H Nebinger
RE: Composite Key Issue
April 11, 2013 5:49 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6134

Join Date: September 1, 2006

Recent Posts

Gnaniyar, may not be the kind of response you're looking for, but I recommend moving access like this into the service layer...

Instead of having external entities create an instance of TestPK to use during creation, I think it's an easier step to go into your TestLocalServiceImpl class an add a method:

1public Test createTest(final int firstKey, final int secondKey) {
2  TestPK testPK = new TestPK();
3  testPK.setFirstKey(firstKey);
4  testPK.setSecondKey(secondKey);
5
6  return createTest(testPK);
7}


After building services, your external entities can now do a much simpler call:

1TestPK = TestLocalServiceUtil.createTest(firstKey, secondKey);


To me this is a much better way to go as a) it hides the fact that there is a PK involved, b) it removes the use of an 'internal' PK class from the caller's code, c) it removes the class loader out of the picture for this class usage pattern, and d) from an API perspective I think it's much cleaner.

Repeat the implementation detail for the getTest(), deleteTest(), etc., as you need.

I also recommend this approach when doing things w/ DQ; moving DQ usage into a method within the service impl class. DQ has similar sorts of things going on (crossing the class loader boundary), and it just seems to me that it makes more sense for DQ stuff to be exposed as a method rather than having external code building dynamic queries against your entity. Exposing a method like "List<Test> findTestsWhereBlahBlahBlah(query args)" means you can still allow external entities to do the searches but your service remains in control of searching the entities, but this may be just my opinion and not others...
Gnaniyar Zubair
RE: Composite Key Issue
April 11, 2013 8:00 AM
Answer

Gnaniyar Zubair

Rank: Liferay Master

Posts: 601

Join Date: December 19, 2007

Recent Posts

Thanks for your solution david. Definitely it should work..

But Still i am getting the exception:

com.test.service.TestLocalServiceUtil.createTest(JI)Lcom/test/model/Test;
David H Nebinger
RE: Composite Key Issue
April 11, 2013 8:16 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6134

Join Date: September 1, 2006

Recent Posts

Is the stack trace from the service consumer, or is it from the TestLocalServiceImpl class?
Gnaniyar Zubair
RE: Composite Key Issue
April 11, 2013 9:02 AM
Answer

Gnaniyar Zubair

Rank: Liferay Master

Posts: 601

Join Date: December 19, 2007

Recent Posts

it is from service consumer while calling TestLocalServiceUtil....
David H Nebinger
RE: Composite Key Issue
April 11, 2013 9:12 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6134

Join Date: September 1, 2006

Recent Posts

Can you show the snippet of code you're using for the call, like you did in the first post?
Gnaniyar Zubair
RE: Composite Key Issue
April 11, 2013 9:33 AM
Answer

Gnaniyar Zubair

Rank: Liferay Master

Posts: 601

Join Date: December 19, 2007

Recent Posts

I did the same as you mentioned:

TestLocalServiceImpl.java :


public Test createTest(long firstKey, int secondKey) {

TestPK testPK = new TestPK();
testPK.setFirstKey(firstKey);
testPK.setSecondKey(secondKey);
return createTest(testPK);

}



I am calling it from external entities :


TestLocalServiceUtil.createTest(firstKey,secondKey);
David H Nebinger
RE: Composite Key Issue
April 11, 2013 9:49 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6134

Join Date: September 1, 2006

Recent Posts

Looks fine. Can you post the full stack trace?
Gnaniyar Zubair
RE: Composite Key Issue
April 11, 2013 10:26 AM
Answer

Gnaniyar Zubair

Rank: Liferay Master

Posts: 601

Join Date: December 19, 2007

Recent Posts

I am getting No Such Method Error :

java.lang.NoSuchMethodError: com.test.service.TestLocalServiceUtil.createTest(JI)Lcom/test/model/Test;


@ this place where i am consuming the service :

TestLocalServiceUtil.createTest(firstKey,secondKey);
David H Nebinger
RE: Composite Key Issue
April 11, 2013 11:32 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6134

Join Date: September 1, 2006

Recent Posts

Then something is out of sync here...

After adding the method to TestLocalServiceImpl, you have to re-run service builder and re-deploy the plugin.

The service consumer must have the new version of the generated service jar (should be automagic if you're using the IDE) and it should be re-built and re-deployed.

Note if you're storing the service jar in the app container's global lib (lib/ext in tomcat), first comment is that you really shouldn't be (unless you need to access the service from a hook), and second comment is that after deploying the service provider be sure to delete the service jar from the deployed plugin (you can't have the service jar in lib/ext and also in the plugin's WEB-INF/lib directory).
Gnaniyar Zubair
RE: Composite Key Issue
April 12, 2013 7:23 AM
Answer

Gnaniyar Zubair

Rank: Liferay Master

Posts: 601

Join Date: December 19, 2007

Recent Posts

Hi David,

your guessing is 100% right...NoSuchMethod Error because of some old version of service jar file.

But it works fine with this code :


public Test createTestTest(long unitId, int itemId) {
Test test = new TestImpl();
test.setUnitId(unitId);
test.setItemId(itemId);
return addTest(test);
}


Instead of this code :

public Test createTest(long unitId, int itemId) {
TestPK testPK = new TestPK();
testPK.setUnitId(unitId);
testPK.setItemId(itemId);
return createTest(testPK);
}


wherever we need to consume the common services, we can include like this in each plugin instead of copying into tomcat/lib/ext.
required-deployment-contexts=my-test-service


But, Would it cause any permanence issue if we use in global path [tomcat/lib/ext] ?

- Gnaniyar Zubair
David H Nebinger
RE: Composite Key Issue
April 12, 2013 8:02 AM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6134

Join Date: September 1, 2006

Recent Posts

Gnaniyar Zubair:
But it works fine with this code :

1    public Test createTestTest(long unitId, int itemId) {
2        Test test =  new TestImpl();
3        test.setUnitId(unitId);
4        test.setItemId(itemId);
5        return  addTest(test);
6    }

This is bad practice and should be avoided. When you call createTest(), you get an instance of Test back, but you have no idea that it is actually a TestImpl. Depending upon a TestImpl may cause your code to break in the future, whereas using createTest(pk) is the standard path that should be more resilient to future changes.

wherever we need to consume the common services, we can include like this in each plugin instead of copying into tomcat/lib/ext.
1required-deployment-contexts=my-test-service

But, Would it cause any permanence issue if we use in global path [tomcat/lib/ext] ?

The biggest issue you face is the deployment issue. Putting the service jar into tomcat's lib/ext directory forces you to:

a) stop tomcat (you cannot change a jar file in lib/ext while tomcat is running).
b) manually move the service jar from the service provider's WEB-INF/lib directory (manually changing an otherwise working hot deployment).

In older versions of Liferay, the app container's global lib dir was the only way to share service jars. Many recommendations on the web still tell you to put the service jar there, but what they don't mention is the version of Liferay the recommendations refer to.

These days (Liferay 6.0 on), the only time a service jar should go here is possibly when you are referencing the service from within a JSP hook. Although there are some legitimate use cases for this, they are few and far between. I'd argue that referencing an outside service jar within a JSP hook is generally a bad practice and based on a bad architecture in most cases.
Gnaniyar Zubair
RE: Composite Key Issue
April 14, 2013 2:58 AM
Answer

Gnaniyar Zubair

Rank: Liferay Master

Posts: 601

Join Date: December 19, 2007

Recent Posts

yes i am considering that issue also, need to use testPersistence , but it is only temporary solution to call addTest method from same impl file as composite entity TestPK is not working properly.

Will find a solution to fix that and update. Thanks