Lombok ile Entity Sınıfı Oluşturma ve JPA Best Practices
Spring Boot / JPA projelerinde Lombok ile temiz bir Entity sınıfı oluşturmak için @Getter, @Setter, @NoArgsConstructor ve @AllArgsConstructor anotasyonlarını kullanmalısınız. Kesinlikle @Data anotasyonunu kullanmaktan kaçının! Aksi halde arka planda üretilen toString() ve hashCode() metotları, Lazy yüklenen ilişkisel (OneToMany vb.) tablolarda sonsuz döngülere (StackOverflowError) ve ciddi performans sorunlarına yol açar.
Bu kapsamlı rehberde Lombok ile entity sınıfı oluşturma konusunu derinlemesine ele alıyoruz. Spring Boot ve JPA projelerinde Lombok kullanarak "boilerplate" (tekrar eden) kod yığınını azaltmayı, kod okunabilirliğini zirveye çıkarmayı ve en önemlisi üretim (production) ortamında baş ağrıtacak hatalardan kaçınmayı öğreneceksiniz.
1. Entity Sınıfı Nedir?
Entity sınıfları, veritabanındaki tabloları Java nesneleri (objeleri) olarak temsil eden sınıflardır. Spring Boot projelerinde genellikle JPA (Java Persistence API) veya Hibernate kullanılarak veritabanı ile uygulama arasındaki köprüyü kurarlar.
Örneğin bir Student tablosu için studentId, firstName, lastName gibi alanları içeren bir Java sınıfı oluşturduğumuzda, geleneksel Java kuralları gereği yüzlerce satır getter, setter ve constructor yazmamız gerekir.
2. Lombok Kütüphanesi Ne İşe Yarar?
Lombok, Java projelerindeki bu kalabalık ve tekrar eden (boilerplate) kodları derleme zamanında (compile time) otomatik olarak üreten harika bir kütüphanedir.
Lombok sayesinde kod dosyasında görünmeyen ancak arka planda var olan şu metotları sadece bir anotasyon ile üretebilirsiniz:
@Getterve@Setter@ToString@EqualsAndHashCode@NoArgsConstructor(Parametresiz Kurucu)@AllArgsConstructor(Tüm Parametreli Kurucu)
3. Lombok Kullanmadan Entity Sınıfı (Eski Yöntem)
Lombok'un değerini anlamak için, Lombok olmadan yazılmış standart bir Entity sınıfına bakalım:
public class Student {
private Long id;
private String firstName;
private String lastName;
// Parametresiz Constructor (JPA için zorunlu)
public Student() {}
// Parametreli Constructor
public Student(Long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
// Getter ve Setter metotları
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
}
Sadece 3 değişken için bile yazılması ve okunması oldukça zahmetli bir kod yığını ortaya çıktı.
4. Lombok ile Entity Sınıfı Nasıl Yazılır?
Lombok Maven Bağımlılığı (pom.xml)
Öncelikle projenizin pom.xml dosyasına Lombok kütüphanesini ekleyin:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
Lombok Kullanarak Student Entity
Aynı Student sınıfını Lombok kullanarak yazdığımızda kodun ne kadar sadeleştiğine bakın:
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
}
5. JPA + Lombok Best Practices (Çok Önemli)
@Data anotasyonunu kullanmayın!
@Data anotasyonu arka planda @ToString, @EqualsAndHashCode, @Getter ve @Setter metotlarının tamamını üretir. Bu durum JPA projelerinde iki büyük felakete yol açar:
- Sonsuz Döngü (StackOverflowError): İki tablo arasında
@OneToManyve@ManyToOneilişkisi varsa,@Data'nın ürettiğitoString()metodu iki tabloyu sürekli birbirini çağırmaya zorlar ve uygulamanız çöker. - Performans Kaybı:
@EqualsAndHashCodemetodu varsayılan olarak sınıftaki tüm değişkenleri kullanır. JPA'da iki nesnenin aynı olup olmadığını karşılaştırmak için tüm alanlara değil, yalnızca veritabanı ID'sine (veya iş anahtarına - business key) bakılmalıdır.
Önerilen Doğru Kullanım Şekli
@Entity
@Table(name="students")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = "studentNumber") // Sadece tekil (unique) bir alana göre karşılaştırma yap!
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable=false, unique=true)
private String studentNumber;
private String firstName;
private String lastName;
}
6. Sık Sorulan Sorular
Lombok kullanmak uygulamanın performansını düşürür mü?
Hayır. Lombok sadece kodu derleme zamanında (compile time) üretir. Uygulama çalışırken (runtime) sanki o getter ve setter metotlarını siz kendi elinizle yazmışsınız gibi çalışır. Performansa sıfır (0) etkisi vardır.
Entity sınıfları içinde @Builder kullanılabilir mi?
Evet, kullanılabilir. Ancak JPA / Hibernate, veritabanından veriyi okurken mutlaka parametresiz bir kurucu (No Args Constructor) arar. Eğer @Builder kullanıyorsanız, sınıfın başına kesinlikle @NoArgsConstructor ve @AllArgsConstructor anotasyonlarını da eklemek zorundasınız.
Sonuç
Lombok ile Entity sınıfı oluşturmak, Spring Boot projelerinde kod kalitesini artıran ve geliştiriciyi yormayan harika bir yaklaşımdır. Ancak JPA'nın çalışma mantığı (özellikle ilişkisel tablolar) nedeniyle, @Data gibi "her şeyi otomatik yapan" anotasyonlardan kaçınılmalı, bunun yerine @Getter ve @Setter gibi kontrollü anotasyonlar tercih edilmelidir.