Foren

Composite Key Issue

thumbnail
Gnaniyar Zubair, geändert vor 11 Jahren.

Composite Key Issue

Liferay Master Beiträge: 722 Beitrittsdatum: 19.12.07 Neueste Beiträge
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
thumbnail
Juan Gonzalez, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Legend Beiträge: 3089 Beitrittsdatum: 28.10.08 Neueste Beiträge
Do you have your portlet service jar in both server classpath and portlet WAR?
thumbnail
Gnaniyar Zubair, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Master Beiträge: 722 Beitrittsdatum: 19.12.07 Neueste Beiträge
I am using global service inside tomcat/ext/lib .
thumbnail
Juan Gonzalez, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Legend Beiträge: 3089 Beitrittsdatum: 28.10.08 Neueste Beiträge
Is that service jar inside your portlet WEB-INF/lib? In that case, try removing it and redeploy.
thumbnail
Gnaniyar Zubair, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Master Beiträge: 722 Beitrittsdatum: 19.12.07 Neueste Beiträge
emoticon From that location only, i can copy and place it in global location.

It is available in both location.

- Gnaniyar Zubair
thumbnail
David H Nebinger, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Legend Beiträge: 14915 Beitrittsdatum: 02.09.06 Neueste Beiträge
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:

public Test createTest(final int firstKey, final int secondKey) {
  TestPK testPK = new TestPK();
  testPK.setFirstKey(firstKey);
  testPK.setSecondKey(secondKey);

  return createTest(testPK);
}


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

TestPK = 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...
thumbnail
Gnaniyar Zubair, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Master Beiträge: 722 Beitrittsdatum: 19.12.07 Neueste Beiträge
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;
thumbnail
David H Nebinger, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Legend Beiträge: 14915 Beitrittsdatum: 02.09.06 Neueste Beiträge
Is the stack trace from the service consumer, or is it from the TestLocalServiceImpl class?
thumbnail
Gnaniyar Zubair, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Master Beiträge: 722 Beitrittsdatum: 19.12.07 Neueste Beiträge
it is from service consumer while calling TestLocalServiceUtil....
thumbnail
David H Nebinger, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Legend Beiträge: 14915 Beitrittsdatum: 02.09.06 Neueste Beiträge
Can you show the snippet of code you're using for the call, like you did in the first post?
thumbnail
Gnaniyar Zubair, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Master Beiträge: 722 Beitrittsdatum: 19.12.07 Neueste Beiträge
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);
thumbnail
David H Nebinger, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Legend Beiträge: 14915 Beitrittsdatum: 02.09.06 Neueste Beiträge
Looks fine. Can you post the full stack trace?
thumbnail
Gnaniyar Zubair, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Master Beiträge: 722 Beitrittsdatum: 19.12.07 Neueste Beiträge
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);
thumbnail
David H Nebinger, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Legend Beiträge: 14915 Beitrittsdatum: 02.09.06 Neueste Beiträge
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).
thumbnail
Gnaniyar Zubair, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Master Beiträge: 722 Beitrittsdatum: 19.12.07 Neueste Beiträge
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
thumbnail
David H Nebinger, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Legend Beiträge: 14915 Beitrittsdatum: 02.09.06 Neueste Beiträge
Gnaniyar Zubair:
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);
	}

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.
required-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.
thumbnail
Gnaniyar Zubair, geändert vor 11 Jahren.

RE: Composite Key Issue

Liferay Master Beiträge: 722 Beitrittsdatum: 19.12.07 Neueste Beiträge
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