Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Ray Augé
ServiceBuilder, Entity referencing collections of Entity
March 29, 2008 7:58 PM
Answer

Ray Augé

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1238

Join Date: February 7, 2005

Recent Posts

Hey All,

I was experimenting tonight and I realized that we can't have an entity
referencing a collection the same type as the entity.

e.g.

1<entity name="Person">
2  ...
3  <column name="siblings" type="Collection" entity="Person"
4mapping-table="Persons_Persons" />
5  ...
6</entity>


This seems like it would be a fairly common type of relationship and
frankly I'm surprised that we don't already support it... though it
seems to only result in problems in one generated file:

1PersonPersistenceImpl


Seems that the inner classes break due to the fact that the referenced
entity have the same pKey name as the referrer. Wondering if perhaps we
could solve this by doing something like if the pKey names are the same
append an underscore to the reference, something like this


 1protected class AddPerson extends SqlUpdate {
 2    protected AddPerson(PersonPersistenceImpl persistenceImpl) {
 3        super(persistenceImpl.getDataSource(),
 4            "INSERT INTO Persons_Persons (personId, personId_) VALUES (?, ?)");
 5
 6        _persistenceImpl = persistenceImpl;
 7
 8        declareParameter(new SqlParameter(Types.BIGINT));
 9        declareParameter(new SqlParameter(Types.BIGINT));
10
11        compile();
12    }
13
14    protected void add(long personId, long personId_) {
15        if (!_persistenceImpl.containsPerson.contains(personId, personId_)) {
16            update(new Object[] { new Long(personId), new Long(personId_) });
17        }
18    }
19
20    private PersonPersistenceImpl _persistenceImpl;
21}



It would be nice to be able to handle these kinds of self references.


Raymond Augé
Software Engineer
Liferay, Inc.
Enterprise. Open Source. For Life.
Jorge Ferrer
RE: ServiceBuilder, Entity referencing collections of Entity
March 30, 2008 3:34 AM
Answer

Jorge Ferrer

LIFERAY STAFF

Rank: Liferay Legend

Posts: 2756

Join Date: August 31, 2006

Recent Posts

Hi Ray,

Fully agreed, we should support that type of references. What I would suggest though is that instead of just adding an underscore I would add a postfix with the number of the relationship. For example:

1personId_siblings


That solves the issue of having several relationships to the same table and it would make the code easier to read.
Ray Augé
Re: [Liferay Forums][Liferay Core Developers]RE: ServiceBuilder, Entity ref
March 30, 2008 6:46 AM
Answer

Ray Augé

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1238

Join Date: February 7, 2005

Recent Posts

> What I would suggest though is that instead of just adding an
> underscore I would add a postfix with the number of the relationship.
> For example:
>
>
1personId_siblings

>
> That solves the issue of having several relationships to the same
> table and it would make the code easier to read.


I like it!
Joel Kozikowski
RE: ServiceBuilder, Entity referencing collections of Entity
March 31, 2008 12:18 PM
Answer

Joel Kozikowski

Rank: Expert

Posts: 405

Join Date: June 27, 2006

Recent Posts

Ray Augé:
1protected class AddPerson extends SqlUpdate {
2    protected AddPerson(PersonPersistenceImpl persistenceImpl) {
3        super(persistenceImpl.getDataSource(),
4            [b]"INSERT INTO Persons_Persons (personId, personId_) VALUES (?, ?)"[/b]);



I've done a lot of work in the ORM area (outside of Liferay). I've even written my own "poor man's persistence" layer that generates ORM code not using Hibernate (when lightweight solutions are needed).

Collections of entities (self referenced, or otherwise) depends on if you are talking about a "one to many" or "many to many" relationship. So, if you are going to refactor ServiceBuilder to support this, you need to be able to specify this "multiplicity" of the relationship.

The "Persons_Persons" join table you describe above is only necessary for a "many to many" relationship, which is actually not nearly as common as the "one to many."

If I have:

EntityA 0..1 ---> 0..* EntityB

(that is, EntityA contains zero or more of EntityB, and EntityB references only zero or 1 of EntityA), then the proper way to "generate" this code is to put a single "foreign key" field in EntityB that is the primary key of EntityA. You then generate a query something like:

1SELECT * FROM EntityB WHERE EntityB.entityA_FK = ?


and you pass in the Id of Entity A. No need for that middle "join" table.

The case of self-referential items is just a special case of the above. If you have Person object, and you wanted a field like "Person biologicalFather", you'd only need to put have a single FIELD that is "biologicalFatherId" in the Person table, and not some third join table.

Of course, in your example, you DO have a "many to many" because any one person can have more than one sibling, and each sibling can also have many. My only point is that the "multiplicity" is an important factor.

The Hibernate guys would argue that you really never have a "many to many" table, because there is usually SOME type of additional information in that "middle" join table beyond the two foreign key references. That is a different debate...

My only point is that if we could express those relationships correctly, you could return a Collection<Entity> using just SQL queries (or, Hibernate queries). I believe by not being able to "express" associations and having the code generate appropriately, we are losing a powerful and significant part of Hibernate's functionality. IIRC, ServiceBuilder DOES have the syntax to express foreign key relationships, but it was disable due to performance issues (but that an altnerate technique surfaced that SHOULD have re-enabled it). I'll see if I can find the post.
jenny heinrich
RE: ServiceBuilder, Entity referencing collections of Entity
May 21, 2008 1:50 AM
Answer

jenny heinrich

Rank: Junior Member

Posts: 47

Join Date: March 14, 2008

Recent Posts

Hello,

I use the ServiceBuilder and it works fine. But I have a question on how to use it
with collections.

My class Page has a one-to-many relationship.
The collection is defined in the service.xml in the entity tag:

<column name="assets" type="Collection" entity="Asset" mapping-key="pId" />

If I load a list of Pages I expected that each page has a method getAssets()
to access the asset list. I add the get / set method to my PageImpl class but
I don´t want to iterate over each element of the list to
load the assets manually for each list entry.

Is there any "best practice" way how to do this using the Service Builder?
Perhaps changing the findAll() method in the ...PersistenceImpl?

Using hibernate I it could be the following:
<set name="assets" inverse="true">
<key column="pId">
<one-to-many class="org.test.Asset"/>
</set>

If I change the hibernate mapping in the ext-hbm.xml it is overwritten by starting the ServiceBuilder.
Is there any possibility to avoid this?

Thanks in advance,

Jenny
Hiran Chaudhuri
RE: ServiceBuilder, Entity referencing collections of Entity
September 10, 2011 1:17 AM
Answer

Hiran Chaudhuri

Rank: Regular Member

Posts: 174

Join Date: September 1, 2010

Recent Posts

jenny heinrich:
If I load a list of Pages I expected that each page has a method getAssets()
to access the asset list. I add the get / set method to my PageImpl class but
I don´t want to iterate over each element of the list to
load the assets manually for each list entry.

Is there any "best practice" way how to do this using the Service Builder?
Perhaps changing the findAll() method in the ...PersistenceImpl?

I do not know whether you solved your problem meanwhile.

But basically what you are searching for is eager loading of those references. It can be configured in Hibernate and other ORM tools.
Who knows how to set this up in ServiceBuilder?
Ray Augé
RE: ServiceBuilder, Entity referencing collections of Entity
September 13, 2011 7:21 AM
Answer

Ray Augé

LIFERAY STAFF

Rank: Liferay Legend

Posts: 1238

Join Date: February 7, 2005

Recent Posts

Why does it have to be eager loading? This is not a smart pattern and should really be avoided.

It's very simple to edit the EntityImpl class that is generated and add methods which return related entites, this way you can also provide for limits (pagination as well).

Check UserImpl class to see examples of methods on users that return relations.
Ivan Valchev
RE: ServiceBuilder, Entity referencing collections of Entity
April 8, 2014 4:29 AM
Answer

Ivan Valchev

Rank: New Member

Posts: 1

Join Date: March 27, 2014

Recent Posts

Any on update on this? Do liferay now supports self referencing in Entities?