# DataTable Composite-Component und ManyToOne



## Tatsu (19. Mrz 2011)

Hallo,
ich habe eine DataTable in der die Einträge einer Entity mit ManyToOne-Verknüpfung zu einer weiteren Entity angezeigt werden. Das funktioniert soweit.

Wenn ich nun die DataTable in eine Komponente auslagere funktioniert die Anzeige nur solange ich nicht auf eine Eigenschaft des Unterobjekts zugreife (ManyToOne).

*Wie gekomme ich das hin, dass die Composite Component auch Eigenschaften des Unterobjekts anzeigt?* Ich hoffe die Frage ist verständlich formuliert. Ich bin Java-Newbie.

Angezeigte Fehlermeldung:

```
/resources/ezcomp/eDataTable.xhtml @31,71 value="#{rowData[cc.attrs.test]}": The class 'de.insecma.ilm.License' does not have the property 'product.shortname'.
```

*Beispiel ohne eigene Composite Component funktioniert:*

```
<p:dataTable id="tbl" var="license" value="#{licenseController.licenseList}">
                <f:facet name="header">
                    DataTable
                </f:facet>

                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Produkt" />
                    </f:facet>
                    <h:outputText value="#{license.product.shortname}" />
                </p:column>

                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Datum" />
                    </f:facet>
                    <h:outputText value="#{license.createdAt}"></h:outputText>
                </p:column>
            </p:dataTable>
```


*Das funktioniert (Verweis auf Property aus der Entity license):*

```
<mc:eDataTable data="#{licenseController.licenseList}" test="createdAt" />
```

*Das funktioniert nicht (Verweis auf Property eines ManyToOne-Objekts der Entity license):*

```
<mc:eDataTable data="#{licenseController.licenseList}" test="product.shortname" />
```

*Die Composite Component:*

```
<!-- INTERFACE -->
        <cc:interface>
            <cc:attribute name="data" />
            <cc:attribute name="test" />
        </cc:interface>

        <!-- IMPLEMENTATION -->
        <cc:implementation>
            <p:dataTable var="rowData" value="#{cc.attrs.data}">
                <f:facet name="header">
                    DataTable
                </f:facet>

                <p:column>
                    <f:facet name="header">
                        <h:outputText value="Produkt" />
                    </f:facet>
                    <h:outputText value="#{rowData[cc.attrs.test]}" />
                </p:column>
            </p:dataTable>
```

*Die Entity-Bean:*

```
@Entity
public class License implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
    @JoinColumn(name = "productId")
    @ManyToOne()
    @NotNull
    private Product product;
    @NotNull
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date createdAt;
```

Vielen Dank im Voraus und ein schönes Wochenende.

Bastian


----------



## Tatsu (20. Mrz 2011)

Hallo alle zusammen,

ich habe die Idee verworfen, da ich nach einigem Lesen zu der Ansicht gekommen bin, dass es besser sein sollte die angepasste DataTable und die Columns jeweils in eine eigene Composite Component auzulagern.

Das könnte dann in etwa so aussehen:

```
<mc:dataTable value="#{licenseController.licenseList}" var="row">
    <mc:column title="Produkt" value="#{row.product.shortname}"/>
    <mc:column title="Erstellt von" value="#{row.cname}"/>
</mc:dataTable>
```

Momentan habe ich hier noch das Problem, dass die TabellenHeader nicht mehr angezeigt werden wenn ich die Column als Composite Component einbaue. Da dies aber ein anderes Thema ist habe ich hierfür eine neues Thema aufgemacht.

Viele Grüße

Bastian


----------



## beachhiker (22. Aug 2011)

Hallo,

versuche für Primeface 3.x eine eigene Komponenten für dataTable und column zu schreiben. Die insertChildren Methode scheint aber wohl nicht für p:dataTable zu funktionieren.

[XML]
<mc:dataTable ....>
    <mc:column .../>
    <mc:column ..../>
</mc:dataTable>
[/XML]


Hat jemand schon ähnliche Erfahrungen gemacht?


----------



## Tatsu (22. Aug 2011)

Hallo beachhiker,



beachhiker hat gesagt.:


> [XML]
> <mc:dataTable ....>
> <mc:column .../>
> <mc:column ..../>
> ...



Ja, bei mir hat das auch nicht funktioniert. 

Meine Lösung, wie folgt:

Die Tabelle

Datei: /resources/ezcomp/dataTable.xhtml

```
...
      xmlns:cc="http://java.sun.com/jsf/composite"
...
        <!-- INTERFACE -->
        <cc:interface>
            <cc:attribute name="value" />
            <cc:attribute name="var" />
        </cc:interface>

        <!-- IMPLEMENTATION -->
        <cc:implementation>
            <p:dataTable id="tbl" 
                         value="#{cc.attrs.value}"
                         paginator="true" rows="10"
                         paginatorTemplate="{CurrentPageReport}  {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                         rowsPerPageTemplate="5,10,15,25,50,100,150,250,500"
                         dynamic="true">
                <c:set target="#{component}" property="var" value="#{cc.attrs.var}"/>
                <cc:insertFacet name="header" />
                <cc:insertChildren />
            </p:dataTable>
        </cc:implementation>
...
```

Die Tabellenzeile

Datei: web.xml
[XML]
<context-param>
        <param-name>javax.faces.FACELETS_LIBRARIES</param-name>
        <param-value>/WEB-INF/ui-compositions/composition-tags.xml</param-value>
</context-param>
[/XML]

Datei: /WEB-INF/ui-compositions/composition-tags.xml
[XML]
<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "facelet-taglib_1_0.dtd"> 
<facelet-taglib>
    <namespace>http://www.my.facelets.component.com/jsf</namespace>
    <tag> 
        <tag-name>column</tag-name> 
        <source>column.xhtml</source>
    </tag>
</facelet-taglib>
[/XML]

Datei: /WEB-INF/ui-compositions/column.xhtml

```
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:cc="http://java.sun.com/jsf/composite"
                ...>

        <!-- Tabellenspalte mit Sotierung und Filter -->
        <c:otherwise>
            <p:column sortBy="#{value}" 
                      filterBy="#{value}"
                      style="#{style}">
                <f:facet name="header">
                    <h:outputText value="#{title}" />
                </f:facet>
                <h:outputText value="#{value}" />
            </p:column>
        </c:otherwise>
    </c:choose>
</ui:composition>
```

Eine JSF-Seite

Datei: irgendwas.xhtml

```
...
<h:form>
            <mc:dataTable var="irgendwas" value="#{fooController.list}">
                <f:facet name="header">Der Titel</f:facet>
                <my:column value="#{irgentwas.irgendeinwert}" title="Ein Title"/>
...
```

Hoffe das hilft weiter. Wenn ja, dann danke klicken.

Grüße

Tatsu


----------



## beachhiker (24. Aug 2011)

Super, jetzt klappt es auch bei mir!

Vielen Dank!


----------



## beachhiker (24. Aug 2011)

In dem Zusammenhang stellt sich nun ein neues Problem. In der Komponenten dataTable übegebe ich einen ActionListner = onRowSelect. Über p:ajax event rufe ich diesen auf was nicht funktioniert. Schreibe ich den Actionlistener direkt in den aufruf p:ajax event funktioniert das event.

[XML] 
<cc:interface>
      <cc:attribute name="id" required="true"/>
      <cc:attribute name="var"  required="true"/>
      <cc:attribute name="value" required="true"/>
      <cc:attribute name="selectionMode" required="true"/>
      <cc:attribute name="selection" required="true"/>
      <cc:attribute name="onRowSelect" method-signature="java.lang.String f()"/>
    </cc:interface>
   <cc:implementation>
      <p:dataTable id="#{cc.attrs.id}"
                value="#{cc.attrs.value}" 
        selectionMode="#{cc.attrs.selectionMode}" 
            selection="#{cc.attrs.selection}"     > 

         <c:set target="#{component}" property="var" value="#{cc.attrs.var}"/>

         <!-- **********  funktioniert *********** -->
         <p:ajax event="rowSelect"  listener=#{kundeBeanHandler.onRowSelect}" update="someElement"/>

         <!-- *********   funktioniert nicht  ****************** -->
          <p:ajax event="rowSelect" listener="#{cc.attrs.onRowSelect}" update="someElement" />    


         <cc:insertFacet name="header" />
         <cc:insertChildren/>  
      </p:dataTable>
  </cc:implementation>
[/XML]

Hat jemand eine Idee oder schon so ein ähnliches Thema?


----------

