Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
James Falkner
ServiceBuilder: Removal of one-to-many mapping
January 24, 2013 10:54 AM
Answer

James Falkner

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1236

Join Date: September 17, 2010

Recent Posts

Hi all,

The Liferay Engineering team wants to know: do you use ServiceBuilder's one-to-many mapping feature? If so, you might not realize that it's inefficient in the way it is implemented, and there are better ways to do it, so the team is considering removing it in a future Liferay version. From the developer:

Service Builder's one to many mapping is totally useless.

The reasons are very simple:

1) on the one side, we generate sql like this(Use TrashEntry as example):
SELECT {TrashVersion.*} FROM TrashVersion INNER JOIN TrashEntry ON (TrashEntry.entryId = TrashVersion.entryId) WHERE (TrashEntry.entryId = ?)

This is logically the same as :
SELECT {TrashVersion.*} FROM TrashVersion WHERE (TrashVersion.entryId = ?)

The inner join is totally useless.

At Service layer, the business logic has already eliminated the possibility that we have a "Many side record without the one side counterpart", use TrashEntry as example, that would mean we have a TrashVersion which does not belong to any TrashEntry. If this is actually happening, we must have a broken business logic or fail to rollback the failure transaction, either case we will see more serious problems than an orphan database record showing on the page.

2) on the many side, we already generate a finder to the one side, still use TrashEntry as example, that would be the "EntryId" finder in TrashVersion.
Since we inject all persistence automatically into service, developer can always call the many side finder to do the query which is much more efficient at both the sql level and cache level.



The removal would simply involve removing the mapping-key attribute from the column element in the ServiceBuilder definition. If this does get removed, it will not happen in the 6.1 family of releases. If you are using this, and have an opinion on this feature, let the team know in this thread!
Mika Koivisto
RE: ServiceBuilder: Removal of one-to-many mapping
January 24, 2013 2:38 PM
Answer

Mika Koivisto

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1499

Join Date: August 7, 2006

Recent Posts

I think I'm missing some point but why not fix it instead of removing it? I think it's also currently very confusing to many developers because it doesn't generate accessor methods in the model or the service it just generates the persistence tier. Most developer will expect Hibernate like functionality where you could do trashEntry.getTrashVersions().
James Falkner
RE: ServiceBuilder: Removal of one-to-many mapping
January 24, 2013 4:37 PM
Answer

James Falkner

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1236

Join Date: September 17, 2010

Recent Posts

Mika Koivisto:
I think I'm missing some point but why not fix it instead of removing it?.


Yeah, I was wondering that too. If the current implementation is inefficient, why not just replace it with the "good/simplified" one - and leave the developer service.xml interface as-is? Then there's no developer impact at all. You just get a faster app.
David H Nebinger
RE: ServiceBuilder: Removal of one-to-many mapping
January 24, 2013 7:31 PM
Answer

David H Nebinger

Rank: Liferay Legend

Posts: 6260

Join Date: September 1, 2006

Recent Posts

Yeah, I personally avoid the one to many because just as Mika said if I get the parent object, I can't do a parent.getChildren() sort of call; I have to go back through the XxxLocalServiceUtil class to use a finder to return the list of children.

So the Hibernate/JPA way, the way we all know and love for non Liferay projects, cannot be replicated because of the missing support for the one to many and many to many relationships, which is extremely sad when you know that under the hood, Liferay is delegating the heavy lifting to Hibernate...

Now since I know how the CLP is doing a lot of the magic to get across the class loader boundary, it should be possible to do some sort of proxy injection to handle the one to many and even the many to many relationship resolutions, but it would be a big chunk of code that would probably end up being the source of more errors and/or confusion than we could even imagine (i.e. trying to ensure the collection of children, when modified, would be handled correctly when handed off to hibernate w/ the appropriate cascade option selected by the developer, handling the lazy designation for the one to many correctly, etc.).

Given that most of us have probably already dropped trying to use one to many sorts of mappings and relying on manual collection management via the child's XxxLocalServiceUtil, dropping support for it would probably not many real-world users, but as Mika suggested having an actual working solution that those using only the service jar could leverage would be preferable...