# json-b + jax-rs + getter mit Parameter = NullPointerException



## Gort (1. Dez 2017)

Hallo,
ich habe hier folgendes Konstrukt:
Ein Rest-Service soll einfach eine JPA-Entity per GET bereitstellen.
Innerhalb dieser Entity ist folgende Methode definiert:


```
public SetpointEntity getLastSetpoint(String source) {
        SetpointEntity result = new SetpointEntity();
        result.setrTUId(this.id);
        switch (source) {
            case ("EVU"):
                result.setSource("EVU");
                result.setSetpoint(lastSetpointPEVU);
                break;
            case ("DSV"):
                result.setSource("DSV");
                result.setSetpoint(lastSetpointPDSV);
                break;
            case ("used"):
                result.setSource("used");
                result.setSetpoint(lastSetpointPUsed);
                break;
            default:
                result = null;
        }
        return result;
    }
```

Das ding ist, dass diese zu einer null-Pointer-Exception führt. Das Problem wird wohl sein, dass eine getter-Methode einen Parameter erwartet, den ich (bzw. jsonb) aber nicht übergebe. Denn benenne ich die Methode um in sagen wir mal retrieveLastSetpoint funktioniert es.
Soweit so gut (oder auch nicht).

Was mir aber nicht in den Kopf will:
Wenn ich diese Methode mit @JsonbTransient (und/oder dem XML-counterpart) annontiere sollte dieser Wert ja garnicht zurückgeliefert werden (was bei anderen Membern der Entity auch offensichtlich funktioniert) trotzdem wird die Exception geworfen.

Ist das 'working as intended'? 

cheers


----------



## truesoul (1. Dez 2017)

Hallo.

Also es ist unüblich solch Logik in ein getter zu haben und es ist unüblich ein Parameter zu übergeben. Die NullPointerException tritt wohl auf da source Null ist und der switch mag keine Null.

Also erstmal solltest nur SetpointEntity zurück geben und die Source wie üblich setzen. Nicht im getter.

Wird die SetpointEntity nicht in der Entität gespeichert? 

Grüße


----------



## mrBrown (1. Dez 2017)

truesoul hat gesagt.:


> Hallo.
> 
> Also es ist unüblich solch Logik in ein getter zu haben und es ist unüblich ein Parameter zu übergeben. Die NullPointerException tritt wohl auf da source Null ist und der switch mag keine Null.
> 
> ...


Das einzig, was man daran kritisieren könnte, ist die Benennung mir „get“, die aber auch völlig valide ist.

Eher wäre das Hinzufügen weiterer Attribute schlechtes Design, soweit man das an diesem Methodenausschnitt beurteilen kann.


----------



## krgewb (1. Dez 2017)

Beispiele für Getter und Setter in Java:

```
public int getWert(){
   return wert;
}

public void setWert(int wert){
   this.wert = wert;
}
```


----------



## truesoul (1. Dez 2017)

mrBrown hat gesagt.:


> Das einzig, was man daran kritisieren könnte, ist die Benennung mir „get“, die aber auch völlig valide ist.



Was denn?  Erst kritisiert du das get und das sagst du das es valide ist? Was denn nun?

Und getter in einer Entität so schreiben ist bei dir auch valide? Wir reden von einer Entitäten die er Im Response  raus geht.

Und wenn dann benennt man die um sie es @Gort gezeigt hat.

Weil getter und setter in der Entität speichern allein die Werte. Solche logik wird anders wo geregelt.

Grüße


----------



## mrBrown (1. Dez 2017)

truesoul hat gesagt.:


> Was denn? Erst kritisiert du das get und das sagst du das es valide ist? Was denn nun?


Man *könnte* es kritisierten, nicht man muss.



truesoul hat gesagt.:


> Und getter in einer Entität so schreiben ist bei dir auch valide? Wir reden von einer Entitäten die er Im Response raus geht.
> 
> Und wenn dann benennt man die um sie es @Gort gezeigt hat.
> 
> Weil getter und setter in der Entität speichern allein die Werte. Solche logik wird anders wo geregelt.


Es ist offensichtlich kein einfacher Getter, da nicht Parameterlos 
Dabei ists auch völlig egal was mit der Klasse gemacht wird und wofür sie benutzt wird - eine Methode die mit "get" anfängt muss nicht zwingend ein typischer Getter sein.

Umbenennen kann man da durchaus machen, aber ist eben nicht zwingend nötig, wenn get* auch ein passender Name ist.


Was mich eher wundert ist dies hier:


Gort hat gesagt.:


> Wenn ich diese Methode mit @JsonbTransient (und/oder dem XML-counterpart) annontiere sollte dieser Wert ja garnicht zurückgeliefert werden (was bei anderen Membern der Entity auch offensichtlich funktioniert) trotzdem wird die Exception geworfen.


----------



## truesoul (1. Dez 2017)

Gort hat gesagt.:


> Was mir aber nicht in den Kopf will:
> Wenn ich diese Methode mit @JsonbTransient (und/oder dem XML-counterpart) annontiere sollte dieser Wert ja garnicht zurückgeliefert werden (was bei anderen Membern der Entity auch offensichtlich funktioniert) trotzdem wird die Exception geworfen.




Ja schauen den die anderen Entitäten aus, wäre die Frage?  Und meine Vermutung ist, dass trotzdem die Methode verwendet wird aber nicht im Json auftaucht. Einfach mal den switch case Block raus nehmen und schauen ob er im Response auftaucht. Was ich nicht glaube.


----------



## Gort (1. Dez 2017)

mrBrown hat gesagt.:


> Umbenennen kann man da durchaus machen, aber ist eben nicht zwingend nötig, wenn get* auch ein passender Name ist.


Leider doch, wie sich herausgestellt hat.



truesoul hat gesagt.:


> Und meine Vermutung ist, dass trotzdem die Methode verwendet wird aber nicht im Json auftaucht.


Das denke ich auch.

Folgendes habe ich noch gemacht, um das ein wenig zu erforschen:
Vor dem Switch auf null geprüft.
Damit geht die Null-pointer-exception weg. Das spricht dafür, dass der code trotz transient ausgeführt wird.

Allerdings kommt dann eine IllegalArgumentException.
Also hab ich das "source" aus der Parameterliste rausgenommen und innerhalb des Bodys auf einen beliebigen Wert gesetzt und siehe da, ich bekomme eine gültige Antwort.

Von daher sollte man (zumindest bei Entitäten (und damit wohl allgemein?!)) tatsächlich nur Getter ohne Parameter verwenden.

edit: Herrje... Hatte bei dem Versuch mit dem Getter und einer leeren Parameterliste das @Transient herausgenommen. Habe es gerade wieder eingefügt und siehe da, die/eine Nullpointerexception ist wieder da...
Gut, dass ich den controller dahingehend umgestrickt habe, dass er die getter der einzelnen Member verwendet und ich von daher nicht mehr auf diesen Sammelgetter angewiesen bin, aber seltsam ists trotzdem


----------



## truesoul (1. Dez 2017)

Ja wenn der Wert aus dem getter im Json auftaucht


----------



## mrBrown (1. Dez 2017)

Was sagt denn der Stacktrace, welcher Aufruf die NPE verursacht?


----------



## mrBrown (1. Dez 2017)

Ich habs jetzt selbst getestet und auch das passende Ticket dazu rausgesucht: https://github.com/eclipse/yasson/issues/34

Die NPE fliegt *nicht* in der Methode, sondern wird vom Marshaller selbst geworfen und hat auch nicht die Methode als Ursache, sondern die Annotation.
Diese war bisher nur möglich, wenn sowohl Feld als auch Getter/Setter vorhanden waren, gab es nur eins von beidem, fliegt die NPE. In Yasson 1.0.1 ist das ganze gefixt, dann funktioniert deine ursprüngliche Variante mit Parameter und Annotation.

Wäre der Parameter das Problem, würde eine spezifische Exception des Marshallers deswegen fliegen.


----------

