# JSF datatable ineinander schachteln



## Marsman (13. Dez 2007)

Hallo Ihr!

Ich möchte in JSF zwei datatables ineinander schachteln. Leider habe ich mit google nix dazu gefunden. Ich hatte an folgende Konstruktion gedacht, funktioniert aber nicht:


```
<h:dataTable var="title" value="#{titleHandler.resultModel}">
	<h:column>
		<h:outputText value="#{title.id}"></h:outputText>
		<h:outputText value=" (#{title.name})"></h:outputText>
	</h:column>
	<h:dataTable var="volume" value="#{title.volumes}">
		<h:column>
			<h:outputText value="#{volume.name}"></h:outputText>
		</h:column>
	</h:dataTable>
</h:dataTable>
```

Es handelt sich bei den Daten um eine 1:n-Relation. Es sollen alle "Titles" aufgelistet werden und je Title die zugehörigen "Volumes". Hat das schon mal jemand gemacht??


Titus


----------



## SnooP (13. Dez 2007)

Was heißt denn geht nich?


----------



## Marsman (13. Dez 2007)

SnooP hat gesagt.:
			
		

> Was heißt denn geht nich?



Die Daten der untergeordneten Tabelle werden nicht angezeigt. Ich vermute deshalb, dass ich etwas falsch mache. Auffällig ist noch, dass in eclipse die Eigenschaft "name" nicht als Teil von "volume" erkannt wird. Die Klasse Volume hat aber den entsprechenden Getter.

Ich wollte eigentlich wissen, ob das überhaupt möglich ist. Und wenn ja, ob jemand ein kurzes Beispiel hätte. Ich habe weder im Buch, noch bei Google dazu etwas gefunden.

Titus


----------



## Informant (14. Dez 2007)

Das geht unteranderem deswegen nicht, da deine geschachtelte DataTable nicht in einer Spalte steht.
Bau da die column tags drumrum und es könnte funktionieren.
Hast du dich schon mal mit RichFaces beschäftigt. Da gibt es auch eine SubTablke die man auf und zu klappen kann, genau für solche Dinge wer du sie vor hast.


----------



## Marsman (14. Dez 2007)

Informant hat gesagt.:
			
		

> Bau da die column tags drumrum und es könnte funktionieren.



Dann erhalte ich folgende Exception:


```
SCHWERWIEGEND: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/sql/Result
```

Titus  :roll:


----------



## freez (14. Dez 2007)

> Bau da die column tags drumrum und es könnte funktionieren.



Genau so hatte ich es auch mal gelöst. Wie schaut denn deine Realisierung in der Bean aus?


----------



## Marsman (20. Dez 2007)

...also das Problem mit der Exception "NoClassDefFoundError" habe ich gelöst. Es lag daran, dass ich die JSTL Bibliothek nicht deployed hatte.

Leider wird meine Tabelle aber immer noch nicht angezeigt. Ich bekomme eine Exception "javax.faces.FacesException: Could not retrieve value of component with path : " zusammen mit "javax.faces.el.PropertyNotFoundException: Bean: org.hibernate.collection.PersistentSet, property: name".

Mir ist irgendwie noch nicht ganz klar, wie ich eine verschachtelte Tabelle programmieren muss. Hier nochmal der JSF-Code (Title steht zu Volume in 1:n Beziehung und name ist eine Eigenschaft von volume):


```
<h:dataTable var="title" value="#{titleHandler.resultModel}">
        <%-- diverse Spalten --%>
	<h:column id="column3">
		<h:outputText value="#{title.style}"></h:outputText>
		<h:outputText value=" (#{title.year})"></h:outputText>
		<h:dataTable var="volume" value="#{titleHandler.resultModel}">
			<h:column id="column31">
				<h:outputText value="#{title.volumes.name}"></h:outputText>
			</h:column>
		</h:dataTable>
	</h:column>
</h:dataTable>
```

Hier die Bean:


```
public class TitleHandler {
	
	private List<Title> result;
	private DataModel resultModel;
	
	private TitleDAO titleDAO;

	public TitleHandler() {
		titleDAO = DAOFactory.getTitleDao();
	}
	public Session getSession() {
		return InitSessionFactory.getInstance().getCurrentSession();
	}
 
	public List<Title> getResult() {
		Transaction tx = getSession().beginTransaction();
		result = titleDAO.findAll();
		tx.commit();
		log.debug(result);
		return result;
	}
	
	public DataModel getResultModel() {
		getResult();
		resultModel = new ListDataModel();
		resultModel.setWrappedData(result);
		return resultModel;
	}
	
	public String view() {
		Title title = (Title) resultModel.getRowData();
		FacesContext fc = FacesContext.getCurrentInstance();
		fc.getApplication().createValueBinding("#{titleViewHandler.title}").setValue(fc, title); 
		return "success";
	}
}
```

Hier die relevante Methode im DAO:


```
public List<Title> findAll() {
	return getSession().createCriteria(Title.class).setFetchMode("volumes", FetchMode.JOIN).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
	}
```


Titus


----------

