Java [JSF][PrimeFaces] DataTable Edit/Delete Funktioniert nicht. Fehler mit der ComboBox?

nintendoluk

Commander
Registriert
Mai 2014
Beiträge
2.124
Hallo zusammen!

Ich baue zurzeit ein kleines JSF Portlet (für Liferay), welches ich auf einen JBoss aufsetze. Dieses Programm baut anhand einer Combobox eine Tabelle auf. Diese Tabelle kann man dann in der "Value"-Zelle editieren, man kann aber auch eine ganze Zelle komplett löschen.
Diese beiden Funktionen laufen aber noch nicht ganz so wie ich will.

Zur verbesserten Anschaulichkeit ist hier mal ein Screenshot von meiner Applikation:
jmxpm.PNG

Und hier ist mein Programm Code (Nur das mMn relevante, damit es übersichtlich bleibt)

JmxPropertyManager.xhtml
Code:
.......
<h:form id="theForm">

	<p:selectOneMenu id="console"
		value="#{jmxPropertyManagerBean.selectedContextName}">
		<f:selectItem itemLabel="Select One" itemValue="" />
		<f:selectItems value="#{jmxPropertyManagerBean.contextNames}" />
		<p:ajax update=":theForm" />
	</p:selectOneMenu>

    .......

	<p:dataTable var="prop" value="#{jmxPropertyManagerBean.properties}"
		editable="true" emptyMessage="Keine Properties gefunden.">
		<f:facet name="header">Properties</f:facet>
	
		<p:ajax event="rowEdit"
			listener="#{jmxPropertyManagerBean.onRowEdit}" />
		<p:ajax event="rowEditCancel" />
	
	
		<p:column headerText="App">
			<h:outputText value="#{prop.appName}" />
		</p:column>
	
		<p:column headerText="Domain">
			<h:outputText value="#{prop.domainName}" />
		</p:column>
	
		<p:column headerText="Property">
			<h:outputText value="#{prop.propertyName}" />
		</p:column>
	
		<p:column headerText="Value">
			<p:cellEditor>
				<f:facet name="output">
					<h:outputText value="#{prop.value}" />
				</f:facet>
				<f:facet name="input">
					<p:inputText value="#{prop.value}" />
				</f:facet>
			</p:cellEditor>
		</p:column>
	
		<p:column style="width:32px">
			<p:rowEditor />
			<p:commandLink styleClass="ui-icon ui-icon-trash"
				style="padding: 0;"
				action="#{jmxPropertyManagerBean.onRowDelete(prop)}">
				<p:confirm header="Löschvorgang"
					message="Wollen Sie das Property wirklich löschen?"
					icon="ui-icon-alert" />
			</p:commandLink>
	
		</p:column>
	
	</p:dataTable>

</h:form>
.....

JmxPropertyManagerBean.Java

Code:
@RequestScoped
public class JmxPropertyManagerBean
{
    String selectedContextName; //Mit Getter & Setter
    List<String> contextNames;
    List<JmxProperty> properties;

    .....

    public void onRowEdit(final RowEditEvent event)
    {
        final JmxProperty property = (JmxProperty) event.getObject();

        saveProperty(property);

        updateProperties();
    }

    public void onRowDelete(final JmxProperty property)
    {
        property.setValue(null);

        saveProperty(property);

        updateProperties();
    }

    public List<String> getContextNames()
    {
        if(this.contextNames == null)
        {
            this.contextNames = loadContextNames(); //Alle Verfügbaren ContextNames werden aus einer Datenbank geladen
        }

        return this.contextNames;
    }

    public List<JmxProperty> getProperties()
    {
        //Zu Testzwecken:
        // setSelectedContextName("JmxPropertyManager");

        if((this.selectedContextName != null) && (this.properties == null))
        {
            updateProperties(); //Hier wird selectedContextName benötigt und die Property-Liste aus einer Datenbank geholt
        }

        return this.properties;
    }

.......

Wenn ich nun auf den Delete-Button (bzw CommandLink) Klicke, kommt zwar die Sicherheitsabfrage, ob man wirklich löschen möchte, aber bei einem Klick auf "Ja" Passiert gar nichts.
Und bei einem Klick auf "Edit" bekommt man zwar die Möglichkeit den Wert umzuschreiben, aber wenn man auf "Accept" oder "Decline" klickt passiert nichts. Die Zelle bleibt einfach ohne Rückmeldung weiter editierbar.

Durchs Debugging weiß ich, dass bei diese Aktionen die Methoden "onRowDelete" und "onRowEdit" erst gar nicht aufgerufen werden.

Auch noch interessant: Wenn ich den Wert (den eigentlich die Combobox festlegen sollte) von selectedContextName Hartgecoded in Zeile 40 der Bean einfüge funktioniert alles einwandfrei. Nur Leider eben nur für eine einzige festgelegte Auswahl.
Das Problem ist also wahrscheinlich, dass der Wert der Combobox zu spät erfasst wird und die Tabelle nicht gefüllt werden kann. Weil PrimeFaces zu dem Zeitpunkt wo es Editieren will keine Tabelle hat, werden auch die Edit/Delete Funktionen erst gar nicht aufgerufen. Soweit meine Vermutung.

Der ganze Spaß wirft übrigens keine einzige Exception oder Fehlermeldung.

Bitte Helft mir! Was soll ich tun? :-(

Viele Grüße
Lukas
 
Naja fernab was sich da jemand wünscht oder nicht, probiere es doch einmal. Wenn es danach klappt weißt du immerhin das es einfach am Scope liegt und du musst entweder eine ganz andere Lösung suchen oder mit dem Vorgaben-Machenden reden.

--- Edit: ---

Nur nochmal zur Klärung. Die Primefaces-Datatable nutzt Ajax-Request, ein Request ist ein Request (egal ob durch AJAX oder "normales" anstoßen des JSF-Lifecycle). Und somit ist für die Verwendung von Componenten die massiv Ajax nutzen der Request-Scope einfach der falsche. Den deine Bean lebt eben immer nur einen Request lang.
 
Zuletzt bearbeitet:
Ich darf nur CDI verwenden. Deshalb hab ich jetzt SessionScoped probiert.

Geht nicht :-/
Ergänzung ()

Ok, ich hab jetzt den "Delete" Button rausgenommen. Der hat irgendeinen Fehler verursacht und aus irgendeinem Grund "Edit" gestört. Jetzt geht wenigstens des Bearbeiten, nur für meinen Auftraggeber ist SessionScoped eigentlich ein No-Go ^^' Eine andere Möglichkeit wäre cool
 
Zuletzt bearbeitet:
Weisst du denn was Session Scoped bedeuted? Weil das Session Scoped ist bestimmt nicht der richtige Scope
 
Das dein Delete-Button fehlerhaft ist wundert mich nicht, das es aber keinen Fehler wirft schon. Wenn du "Action" verwendest, dann muss die Rückgabe ein String sein, bei "ActionListener" muss die "Rückgabe" void sein.

Und das Session-Scoped ein NoGo ist mag ok sein, deswegen habe ich Viewscope vorgeschlagen ;)
 
Danke Umbel, das schau ich mir morgen an :-)

Ich hab jetzt auch ein Problemgelöst, sodass der Edit Button funktioniert. Liferay speichert jetzt den Inhalt meiner Combobox über LiferayPortletHelper.setPortletSessionAttribute() und .getPortletSessionAttribute()
 
Zurück
Oben