Diyelimki AccountRepository'si var. Altına da sorguları ekliyoruz böyle. Belki hata verir böyle aynı isimde yazarsak, ona bir şey diyemem şimdilik. (Yani alttaki gibi repostiroy'e tanımlarsak, Spring ya da JPA özel sorgulara dönüştürüyor);
Aslinda genel olarak ne zaman Optional kullanmaliyiz ile ayni soru bu. JPA sadece bu yapiya uyum sagliyor.
Eger kodun geri kalaninda fluent fonksiyonel programlama yapiliyorsa Optional kullanmak yegdir.
Yine interface'e bakan kisi, bu alanin "null" olabilecegini tek okuyusta anlayabilmis olur. Kotlinde oldugu gibi nullable olmayan tipler Java'da @NonNull gibi annotasyonlar disinda tanimlanamadigi icin Optional olmayan return parametresinin null olmadigini varsayarim ben. Aksi halde kodun her tarafi " x != null" kontrolleri ile dolu olur.
Optional kullanarak interface i implemente eden ve kullanan insanlara bu alanin null olabilecegini ve null durumu handle etmelerini zorunlu kilmis olursun bu da kod kalitesini arttirir.
Ancak Optional da silver bullet degil; != yerine ifPresent() kullanarak semantik olarak ayni seyi farkli sekilde yapmis oluyorsun. Sadece daha okunabilir olmus oluyor. Ayrica ufak da olsa bir performans farki da var, surekli wrapper yaptigin icin. Son aklima gelen dezavantaj da serialization. Optional<Type> serialize etmek icin biraz daha ugrasman gerekiyor direkt Type serializasyonuna kiyasla.
Isminde "findBy" gectigi icin Optional<Account> olmali. Bunu yaparak bu fonksiyonu cagiran her yerde Account bulunamama durumunu handle etmeye zorlamis oluyorsun ki olmasi gereken bu. Cagiran yer de isterse bunu kendisi handle eder isterse o da kendisini cagiran yere delege eder.
Direkt "Account findByEmail()" seklinde yaparsan cagiran yerde null-safety zorlamasi olmaz. Bazen null bazen null olmayan tipler genel olarak proje buyudukce basa bela olurlar.
Biraz code review gibi olacak ama bence soyle olsa daha dogru:
1. DB tanimlarken email ve username alanlarini "unique" index ve muhtemelen not nullable yaparsan
2. Email ve username kullaniliyor mu diye kontrol etmeden direkt insert edersen
3. Kullanilmasi durumunda gelen exception'i handle ederken "Constraint hede hodo failed" olmasindan bunu anlarsin. Boylece her basarili kayit icin 3 yerine 1 defa DB ye istek atmis olursun. Birak o validasyonu RDBMS yapsin senin icin insert ederken.
Ayrica JPA da "existsByX" template'i var. Butun User alanlarini doldurmasindansa sadece bununla eslesen kayit var mi yok mu bana getir seklinde kullanabilirsin. Optional kullanmana da gerek kalmaz, ya true ya da false donecek zira.
User'a @NotNull eklemene gerek yok, cunku o runtime validasyon annotasyonu. CreateUser 'da kontrol edilmesi yeterli. Ayrica @NotBlank zaten null kontrolu yapiyor, ikisine ayni anda gerek yok.
User'da this.enabled=false yapilan kisim da database de yapilabilir "default false" seklinde. Ama bu haliyle de bence anlasilir. JPA zaten varsa kendi default constructor'i kullaniyor.
Su haliyle insert ederken yapilacak exception handling de eklenirse bence gayet iyi.
Buradaki "catch" blogu ayri bir fonksiyon olabilir. Cok muhtemelen kullanici kendi hesabini update ederken de ayni seyi yapman gerekecek. ( Yeni email adresi kullanimda mi vs )
Java:
try{
repo.save(user)
}catch(Exception e){
if (e instance of ConstraintViolationException){ // farkli bir err olabilir, hatirlamiyorum tam class'i
final String errMsg = e.getMessage();
if(errMsg.contains("username")) {
throw new UsernameInUseException(user.userName);
}else if(errMsg.contains("email")){
// email in use
}else{
throw new InternalError(e);
}
}
}
User'a @NotNull eklemene gerek yok, cunku o runtime validasyon annotasyonu. CreateUser 'da kontrol edilmesi yeterli. Ayrica @NotBlank zaten null kontrolu yapiyor, ikisine ayni anda gerek yok.
User'da this.enabled=false yapilan kisim da database de yapilabilir "default false" seklinde. Ama bu haliyle de bence anlasilir. JPA zaten varsa kendi default constructor'i kullaniyor.
Su haliyle insert ederken yapilacak exception handling de eklenirse bence gayet iyi.
Buradaki "catch" blogu ayri bir fonksiyon olabilir. Cok muhtemelen kullanici kendi hesabini update ederken de ayni seyi yapman gerekecek. ( Yeni email adresi kullanimda mi vs )
Java:
try{
repo.save(user)
}catch(Exception e){
if (e instance of ConstraintViolationException){ // farkli bir err olabilir, hatirlamiyorum tam class'i
final String errMsg = e.getMessage();
if(errMsg.contains("username")) {
throw new UsernameInUseException(user.userName);
}else if(errMsg.contains("email")){
// email in use
}else{
throw new InternalError(e);
}
}
}
@bitwise hocam peki neden final anahtarı ile bir String oluşturduk? final String errMsg = e.getMessage();
e.getMessage(); o an zaten değiştirilemez bir mesaj değil midir?
@bitwise hocam peki neden final anahtarı ile bir String oluşturduk? final String errMsg = e.getMessage();
e.getMessage(); o an zaten değiştirilemez bir mesaj değil midir?
Rica ederim. Bu arada ben "ConstraintViolationError" hatasini uydurdum, gercekte atilan exception nedir gelistirme bitince bana yazabilir misin? Onu da merak ediyorum.
Rica ederim. Bu arada ben "ConstraintViolationError" hatasini uydurdum, gercekte atilan exception nedir gelistirme bitince bana yazabilir misin? Onu da merak ediyorum.