tags:

views:

43

answers:

1

How does Seam Framework handle composite primary keys in pages.xml using EntityHome?

The usual approach is to assign an ID to entityHome components, like:

<page view-id="/team-list.xhtml">
  <param name="club" value="#{clubHome.id}" converterId="javax.faces.Integer" validatorId="javax.faces.LongRange" />
</page>

This assigns the (atomic) ID to clubHome from the URL

http://...?club=12345...

but what's the technique to apply for entities using composite primary keys? Here the key is composed of (roundId, ordinalNumber), giving a URL

http://...?round=143&amp;group=1...

<page view-id="/standings.xhtml">
  <param name="group" value="#{groupHome.setId(new GroupId(round???, group???))}" />
</page>

The above is a non-working attempt to assign a new composite ID to groupHome. The problem here is how to reference the URL params. (Is there a way to create temp vars in pages.xml?)

Other than that, I see no other way but to assign the atomic PK properties to member variables in one or several different EntityHome components, of course requiring EntityHome subclasses with resprective getters and setters:

@Name("groupHome")
public class GroupHome extends EntityHome<Group>
{
    // temp var
    private Integer ordinalNumber;

    public void setOrdinalNumber(Integer ordinalNumber)
    {
        this.ordinalNumber = ordinalNumber;
    }

    public Integer getOrdinalNumber()
    {
        return ordinalNumber;
    }

}

Used as following from pages.xml:

<page view-id="/standings.xhtml">
  <param name="round" value="#{roundHome.id}" />
  <param name="group" value="#{groupHome.ordinalNumber}" />
</page>

So, what's the best practice here? I can neither find any examples using composite primary keys in "Seam in Action" nor in/on the net.

+2  A: 

You can use the following

Mark your GroupId as @Scope(ScopeType.EVENT)

@Name("groupId")
@Scope(ScopeType.EVENT)
@AutoCreate
public class GroupId implements Serializable {

    private Integer id;
    private Integer ordinalNumber;

}

Set up your page as

<page view-id="/standings.xhtml">
    <param name="round" value="#{groupId.id}" />
    <param name="group" value="#{groupId.ordinalNumber}"/>
    <action execute="#{groupHome.setId(groupId)}"/>
</page>
Arthur Ronald F D Garcia
Where have you been? :) (+1)
Pascal Thivent
@Kawu Prefer to use other name than **id** when you have a composite primary key
Arthur Ronald F D Garcia
@Pascal Thivent No free time. I am working on a corporative project which consumes my time. It is open source. I will notify you when published. Thank you anyway.
Arthur Ronald F D Garcia
@Arthur: I never call properties id when they are composite (it's roundId here).
Kawu
@Arthur: my entity classes are all generated, they only carry the @Name annotation exactly the way you described. Doesn't that suffice? What do I need the @Scope and @AutoCreate for?
Kawu
@Kawu @AutoCreate instructs Seam to create your component if not available. The default scope for plain POJO's is ScopeType.CONVERSATION. It does not make sense to use a ScopeType.CONVERSATION on a composite primary key class. So i prefer to use ScopeType.EVENT (per request)
Arthur Ronald F D Garcia
@Arthur: thanks for the info. I'm not that far into Seam yet, so I'll just leave understanding this as an exercise for later, especially the scope thing. (Note, all my components so far use the default scope and I've never seen Seam - or rather JSF/EL - not instantiate any requested components...)
Kawu