# JpaRepositories & Hibernate: ungewolltes trim() in findBy



## SimProtect (17. Mrz 2017)

Hallo,
Ich habe ein Problem zu lösen, das mir momentan echte Kopfschmerzen bereitet. Wir haben derzeit JpaRepositories und Hibernate am Laufen. In einem Controller soll - als zweite Sicherheitsinstanz - nochmal geprüft werden, ob eine Entität bereits in der Datenbank existiert. Maßgebend hierbei ist nicht die UUID des Objekts (diese kann abweichen, da das Objekt vom Client rüberkommt und es sich vielleicht um ein neues Objekt handelt, das fälschlicherweise an den Sicherheitsmechanismen vorbeigekommen ist), sondern ein bestimmtes Field dieses Objekts - dieses muss eindeutig sein.

Die entsprechende Prüfung im Controller sieht wie folgt aus:


```
public User createUser(User user) {
        User existingUser = this.userRepository.findFirstByUsername(user.getUsername());
        if (existingUser == null) {
            return this.userRepository.save(user);
        } else {
            return null;
        }
    }
```


Nun hat sich folgendes Problem ergeben:

Wir erstellen zunächst einen User mit dem Usernamen "EinNutzer". Dieser wird korrekt in der Datenbank hinterlegt
Wir versuchen nun einen User mit dem Usernamen "EinNutzer " (<- Leerzeichen am Ende) zu erstellen. Durch unsere GUI kommt das auch sauber durch, weil eine derartige Unterscheidung derzeit nicht durch die Anforderungen ausgeschlossen sind und wir dem eigentlichen Nutzer nicht die Möglichkeit nehmen sollen, auch solche Dinge zu tun.
Die oben hinterlegte Methode jedoch legt den User nicht an, da es ihn bereits gibt.
Offensichtlich sind in der Logik "EinNutzer" und "EinNutzer " gleich, denn das gibt uns das JPARepository zurück, wenn ich den zweiten String auf die Datenbank loslasse.
Meine Frage ist jetzt: Kann ich das irgendwo einstellen bzw. ist das vielleicht irgendwo schon versehentlich eingestellt worden? Wenn ja: Wo
Bisher bin ich bei meinen Recherchen nur darauf gestoßen, dass Leute das genaue Gegenteil haben wollen. 

Ich wäre hier für einen Ratschlag sehr dankbar.

Mit besten Grüßen
SimProtect


----------



## Thallius (17. Mrz 2017)

Wieso machst du nicht einfach den genaueren Vergleich noch eben selber? Ist eine Zeile Code...


----------



## stg (17. Mrz 2017)

Ist "existingUser" hier tatsächlich ungleich null? (Mit Debugger prüfen)
Wie sieht die Implementierung von User und UserRepository aus?


----------



## SimProtect (17. Mrz 2017)

Tatsache ist der existingUser != null. Das hatte ich direkt geprüft. Auch kommt das Objekt, was im Controller ankommt noch MIT Leerzeichen an. Das Leerzeichen geht als nicht beim Weg über das Netzwerk o.Ä. verloren.

Das Repository:

```
public interface IUserRepository extends JpaRepository<User, UUID> {

    User findFirstByUsername(String username);
}
```

Es folgt ein Ausschnitt des Nutzers - auf das wesentliche gekürzt. Die Datenbankeinträge habe ich allerdings durch Sternchen ersetzt. Ansonsten befinden sich dort nur "gewöhnliche" Getter und Setter.


```
@Entity
@Table(schema = "[****]", name = "****")
public class User extends AbstractBusinessObject{
   @Column(name = "****")
   @NotNull
   @Length(min = 1, max = 60)
   private String username;
}
}
```




> Wieso machst du nicht einfach den genaueren Vergleich noch eben selber? Ist eine Zeile Code...


Weil das von unserem CP nicht gewollt ist. Um ihn davon zu überzeugen, muss ich zumindest genau darlegen, woran das wirklich liegt. Eine Aussage wie "an Hibernate" o.Ä. ist da bei uns nicht ausreichend.


----------



## stg (17. Mrz 2017)

Ich würde nochmal prüfen, welcher String tatsächlich an die find-Methode übergeben wird und welcher SQL query anschießend tatsächlich abgesetzt wird.
Geht hier das Leerzeichen verloren, dann funkt sicher Spring irgendwo dazwischen.
Ist es vorher schon verschwunden, dann passiert vielleicht doch was im Getter oder auf dem Weg dorthin.
Ist es im Query immer noch vorhanden, dann vielleicht auf Datenbankebene weitersuchen.

Ich hab Spring selbst nie verwendet, daher weiß ich nicht genau, wo man suchen muss, wenn Spring hier das Problem ist. Ich kann mir aber nur schwer vorstellen, dass das allgemein immer so gehandhabt wird, dass wortlos Strings getrimt werden. Da wird dann wohl in irgendeiner Konfiguration was dazwischengeschaltet sein. Ich hab von (Web)DataBinder gelesen, mit dem man sowas wohl anstellen könnte...


----------



## SeriousD0nkey (17. Mrz 2017)

Wenn du erst den Benutzer mit Leerzeichen versuchst du speichern wird der auch ohne Leerzeichen in der Datenbank abgelegt? Habe mal gelesen, dass einige JPA Provider automatisch Leerzeichen am Anfang bzw. Ende des Strings kürzen. Aber ich weiß nicht mehr ob Hibernate dazu zählte. Müsste ich nochmal im Internet suchen.


----------



## SimProtect (24. Mrz 2017)

Erstmal entschuldige ich mich für die späte Reaktion. Leider hatte ich irgendwie Probleme mit meinem Account hier, sodass ich schlicht und ergreifend nicht mehr antworten konnte.

Also wir haben das Problem mittlerweile finden können. Tatsächlich hatte das ganze mit einer bestimmten Einstellung der Datenbank zu tun, welche die jeweilige Spalte mit Leerzeichen aufgefüllt hatte. Dadurch waren - im oben genannten Beispiel - die beiden Einträge gleich. Diese Einstellung ließ sich nachträglich nicht mehr korrigieren bzw. wurde 'irgendwann' im Rahmen eines "ALTER TABLE"-Befehl automatisch wieder gesetzt (Aussage unserer Datenbankabteilung).

Das Problem ließ sich dadurch umgehend, dass wir findByLike[...] statt findBy verwenden - was in unserem Falle auch tatsächlich als Lösung ausreicht.


----------



## stg (24. Mrz 2017)

"Und der Datenbank-Admin so: Ups..."


----------

