Forums

Home » Liferay Portal » English » 3. Development

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Peter Hellstrand
Service Builder get applications
March 15, 2012 1:57 PM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

Hi
I am trying to use the service builder. This build does not succed

1
2[javac]     Collection applications)
3[javac] Collection cannot be resolved to a type


but I hope you understand what I am trying to do. I would like to have class Function to have a collection of Application objects. I would like to do this.

1
2List<Application> applications = function.getApplications();
3function.addApplication(application);  // I gues this one I have to create by my self in FunctionLocalServiceImpl
4


 1
 2
 3        <entity name="Application" local-service="true" remote-service="false">
 4        <column name="applicationId" type="long" primary="true" />
 5        <column name="name" type="String"/>
 6        <finder name="Id" return-type="Application">
 7            <finder-column name="applicationId" />
 8        </finder>
 9    </entity>
10
11    <entity name="Function" local-service="true" remote-service="false">
12        <column name="functionId" type="long" primary="true" />
13        <column name="name" type="String"/>
14        <column name="applications" type="Collection" entity="Application" mapping-key="applicationId"/>
15        <finder name="Id" return-type="Function">
16            <finder-column name="functionId" />
17        </finder>
18        <finder name="Applications" return-type="Collection">
19            <finder-column name="applications" />
20        </finder>   
21    </entity>



So, to summarize, how do you work with collections in service builder?

Thanks
David H Nebinger
RE: Service Builder get applications
March 15, 2012 2:45 PM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 11295

Join Date: September 1, 2006

Recent Posts

There is already finders by primary key. Entities should be defined as:

 1
 2     <entity name="Application" local-service="true" remote-service="false">
 3        <column name="applicationId" type="long" primary="true" />
 4        <column name="name" type="String"/>
 5    </entity>
 6
 7    <entity name="Function" local-service="true" remote-service="false">
 8        <column name="functionId" type="long" primary="true" />
 9        <column name="name" type="String"/>
10        <column name="applications" type="Collection" entity="Application" mapping-key="applicationId"/>
11    </entity>


The persistence layer already has a method to get all entities, you just need to expose it in ApplicationLocalServiceImpl:

1
2public List<Application> getAllApplications() throws Exception {
3  return applicationPersistence.findAll();
4}


Adding a new application is done via the following code:

1
2Application app = ApplicationLocalServiceUtil.createApplication(0);
3...
4ApplicationLocalServiceUtil.addApplication(app);
Peter Hellstrand
RE: Service Builder get applications
March 15, 2012 2:46 PM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

OK i found this in FunctionPersistence

1
2public List<no.appo.services.model.Application> getApplications( long pk) throws SystemException {
3    return getApplications(pk, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
4}


but still no way to add a Application to a function
Hitoshi Ozawa
RE: Service Builder get applications
March 15, 2012 2:51 PM
Answer

Hitoshi Ozawa

Rank: Liferay Legend

Posts: 7949

Join Date: March 23, 2010

Recent Posts

Service builder doesn't generate method to add methods. You'll have t o add it yourself in the Impl method. Just add a method to add a single Application and a method to add a List of Applcations which iterates through to call the single add method.
Peter Hellstrand
RE: Service Builder get applications
March 15, 2012 3:02 PM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

How do you suggest implementing the addAppliction?

 1
 2public class FunctionImpl extends FunctionBaseImpl {
 3    /*
 4     * NOTE FOR DEVELOPERS:
 5     *
 6     * Never reference this class directly. All methods that expect a function model instance should use the {@link no.capraconsulting.appo.services.model.Function} interface instead.
 7     */
 8    public FunctionImpl() {
 9    }
10   
11    public void addApplication(Application application){
12       
13    }
14   
15}
Hitoshi Ozawa
RE: Service Builder get applications
March 15, 2012 3:18 PM
Answer

Hitoshi Ozawa

Rank: Liferay Legend

Posts: 7949

Join Date: March 23, 2010

Recent Posts

public class FunctionLocalServiceImpl extends FunctionLocalServiceBaseImpl {
public Application addApplication(int id,....){
....
}

public Application addApplication(List application){
// just iterate through calling addApplication(int id)
}
Peter Hellstrand
RE: Service Builder get applications
March 16, 2012 3:16 AM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

Thank you

But my concern is the connection between Applications and Functions.
Is application.setFunction(functionId) what needs to be done?
Peter Hellstrand
RE: Service Builder get applications
March 16, 2012 1:29 PM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

I tried this

1this.functionPersistence.getApplications(function.getFunctionId(), QueryUtil.ALL_POS, QueryUtil.ALL_POS).add(application);


but that list was read only.
David H Nebinger
RE: Service Builder get applications
March 16, 2012 1:52 PM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 11295

Join Date: September 1, 2006

Recent Posts

To add an application, you'd call (in order):

Application app = ApplicationLocalServiceUtil.createApplication(primary key);
ApplicationLocalServiceUtil.addApplication(app);

To add the application to the function (which seems kinda backwards to me, btw):

Function func = FunctionLocalServiceUtil.getFunction(funcPrimKey);
func.getApplications().add(app);
FunctionLocalServiceUtil.updateFunction(func);
Peter Hellstrand
RE: Service Builder get applications
March 16, 2012 1:58 PM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

Thank you
This is the line i have been looking for.
1func.getApplications().add(app);

My problem is that my function does not have a getApplications() or similar method.
That is what I don't understand.


 1
 2   
 3    <entity name="Function" local-service="true" remote-service="false">
 4        <column name="functionId" type="long" primary="true" />
 5        <column name="name" type="String"/>
 6        <column name="functionalAreaId" type="long" />
 7        <column name="applications" type="Collection" entity="Application" mapping-key="applicationId"/>
 8        <finder name="Id" return-type="Function">
 9            <finder-column name="functionId" />
10        </finder>
11        <finder name="FunctionalArea" return-type="Collection">
12            <finder-column name="functionalAreaId" />
13        </finder>
14    </entity>
15   
David H Nebinger
RE: Service Builder get applications
March 16, 2012 2:04 PM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 11295

Join Date: September 1, 2006

Recent Posts

I think you should have a method like that since it is defined as part of the entity...

And you should still get rid of the Id finder since it duplicates the primary key method...
Peter Hellstrand
RE: Service Builder get applications
March 16, 2012 2:30 PM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

There is no such method but I agree with you that i should be. All other columns have get methods except from this one
1 <column name="applications" type="Collection" entity="Application" mapping-key="applicationId"/>





The extra finder is a result from this thread. (data base chaching)
http://www.liferay.com/community/forums/-/message_boards/message/12838482


Edit: Found this in the documentation so i guess you are right. I cant find any difference from my column though

For example:
<column
name="shoppingItemPrices"
type="Collection"
entity="ShoppingItemPrice"
mapping-key="itemId"
/>

The above column specifies that there will be a getter called
pojo.getShoppingItemPrices() that will return a collection. It will map to a
column called itemId in the table that maps to the entity ShoppingItemPrice.

If the entity and mapping-table attributes are specified and mapping-key is not,
then the Service Builder will assume you are specifying a many to many
relationship.
Peter Hellstrand
RE: Service Builder get applications
March 17, 2012 6:04 AM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

I used reflections to find all methods on my Function interface. I also created a new project and called it whit a copy paste of David H Nebinger entities from the post above. Same result.



Name: persist
Name: equals
Name: toString
Name: hashCode
Name: clone
Name: compareTo
Name: compareTo
Name: getName
Name: setName
Name: getPrimaryKey
Name: getExpandoBridge
Name: setPrimaryKey
Name: getPrimaryKeyObj
Name: setPrimaryKeyObj
Name: setExpandoBridgeAttributes
Name: toCacheModel
Name: toEscapedModel
Name: toEscapedModel
Name: toXmlString
Name: resetOriginalValues
Name: getModelClass
Name: getModelClassName
Name: getColumnBitmask
Name: getFunctionId
Name: getOriginalFunctionalAreaId
Name: getFunctionalAreaId
Name: getOriginalFunctionId
Name: setFunctionId
Name: setFunctionalAreaId
Name: isNew
Name: setNew
Name: isCachedModel
Name: setCachedModel
Name: isEscapedModel
Name: wait
Name: wait
Name: wait
Name: getClass
Name: notify
Name: notifyAll



Can I have a working service.xml from any of you that is actually working so I can compare with my?

Edit. I actually downloaded service.xml from "Liferay in action" source code. That code does no generate getter methods for the collections ether.
Peter Hellstrand
RE: Service Builder get applications
March 17, 2012 10:04 AM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

More people with the same issue

http://www.liferay.com/community/forums/-/message_boards/message/11747895
Peter Hellstrand
RE: Service Builder get applications
March 18, 2012 11:51 AM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

Is it fair to report a bug on this one? Could someone else be kind and try to run any service.xml in a new project just to see if getters and setters are generated for the collections.
David H Nebinger
RE: Service Builder get applications
March 18, 2012 2:11 PM
Answer

David H Nebinger

Community Moderator

Rank: Liferay Legend

Posts: 11295

Join Date: September 1, 2006

Recent Posts

Well, the answer is actually to review the service builder code... I'm going through the 6.0 EE SP2 source, but I'm guessing it's going to be the same for the CE lines...

When SB is parsing an entity, it distinguishes between a regular column and a collection column. Collection columns are tracked separately.

The com.liferay.portal.tools.servicebuilder.dependencies.model.ftl (the template used to generate the model interface) only creates getters/setters for regular columns, not any of the collection columns.

The weird thing is that I cannot find any reference to the collectionList member of com.liferay.portal.tools.servicebuilder.Entity outside of the initial population.

Since the model.ftl only works off of the regular columns of the Entity class, the collections will always be excluded from the model, as well as all of the other classes.

Doing a global search of the portal source, it would appear that the collectionList member is not referenced anywhere, and this is most likely a bug.
Peter Hellstrand
RE: Service Builder get applications
March 18, 2012 3:20 PM
Answer

Peter Hellstrand

Rank: Regular Member

Posts: 167

Join Date: November 30, 2011

Recent Posts

Thank you very much for your efforts. This one was driving me crazy. emoticon
Is there any work around to work with a collection? Do I have to go download a older SDK or wait?

Edit: I have reported it
http://issues.liferay.com/browse/LPS-26147