Bir süredir JPA (Hibernate uygulaması) ile çalışıyorum ve her zaman kendimi AccessType, değişmez özellikler, eşittir / hashCode, ... gibi sorunlarla boğuşuyor buluyorum.
Bu yüzden her bir konu için genel en iyi uygulamayı bulmaya ve bunu kişisel kullanım için yazmaya karar verdim.
Ancak kimse bu konuda yorum yapmak ya da bana nerede yanlış olduğumu söylemek için sakıncası olmaz.
Varlık Sınıfı
Serializable uygulamak
Sebep: Spesifikasyon yapmanız gerektiğini söylüyor, ancak bazı JPA sağlayıcıları bunu zorlamıyor. JPA sağlayıcısı olarak hazırda bekletme bunu zorlamaz, ancak Serializable uygulanmadıysa, ClassCastException ile midesinde derin bir yerde başarısız olabilir.
Kurucular
varlığın tüm zorunlu alanlarını içeren bir kurucu oluşturun
Sebep: Bir kurucu daima oluşturulan örneği aklı başında bir durumda bırakmalıdır.
Bu kurucu yanı sıra: bir paket özel varsayılan kurucu var
Sebep: Varsayılan yapıcı, Hazırda Bekletme öğesinin varlığı başlatmasını gerektirir; private'a izin verilir, ancak çalışma zamanı proxy üretimi ve bayt kodu araçları olmadan verimli veri alımı için paket özel (veya genel) görünürlüğü gerekir.
Alanlar / Özellikler
Genel olarak saha erişimini ve gerektiğinde mülk erişimini kullanın
Sebep: Bu muhtemelen en tartışmalı konudur, çünkü biri veya diğeri için net ve ikna edici argümanlar yoktur (mülk erişimi ve saha erişimi); bununla birlikte, daha net kod, daha iyi kapsülleme ve değişmeyen alanlar için ayarlayıcılar oluşturmaya gerek olmaması nedeniyle saha erişimi genel favori olarak görünmektedir
Değiştirilemez alanlar için ayarlayıcıları atla (erişim türü alanı için gerekli değildir)
- özellikler özel olabilir
Neden: Korumalı (Hazırda Bekleme) performansı için daha iyi olduğunu duydum ama Web'de bulabildiğim tek şey: Hazırda Bekletme genel, özel ve korumalı erişimci yöntemlerinin yanı sıra genel, özel ve korumalı alanlara doğrudan erişebilir . Seçim size kalmış ve uygulama tasarımınıza uyacak şekilde eşleştirebilirsiniz.
Eşittir / hashCode
- Bu kimlik yalnızca varlık devam ederse ayarlanmış bir kimliği asla kullanmayın
- Tercihen: benzersiz bir İş Anahtarı oluşturmak için değişmez değerler kullanın ve bunu eşitliği test etmek için kullanın
- benzersiz bir İş Anahtarı yoksa , varlık başlatıldığında oluşturulan geçici olmayan bir UUID kullanın ; Daha fazla bilgi için bu harika makaleye bakın .
- asla ilgili varlıklara başvurmayın (ManyToOne); bu varlığın (üst varlık gibi) İşletme Anahtarının bir parçası olması gerekiyorsa, yalnızca kimlikleri karşılaştırın. Bir proxy'de getId () öğesini çağırmak, özellik erişim türünü kullandığınız sürece varlığın yüklenmesini tetiklemez .
Örnek Varlık
@Entity
@Table(name = "ROOM")
public class Room implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue
@Column(name = "room_id")
private Integer id;
@Column(name = "number")
private String number; //immutable
@Column(name = "capacity")
private Integer capacity;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "building_id")
private Building building; //immutable
Room() {
// default constructor
}
public Room(Building building, String number) {
// constructor with required field
notNull(building, "Method called with null parameter (application)");
notNull(number, "Method called with null parameter (name)");
this.building = building;
this.number = number;
}
@Override
public boolean equals(final Object otherObj) {
if ((otherObj == null) || !(otherObj instanceof Room)) {
return false;
}
// a room can be uniquely identified by it's number and the building it belongs to; normally I would use a UUID in any case but this is just to illustrate the usage of getId()
final Room other = (Room) otherObj;
return new EqualsBuilder().append(getNumber(), other.getNumber())
.append(getBuilding().getId(), other.getBuilding().getId())
.isEquals();
//this assumes that Building.id is annotated with @Access(value = AccessType.PROPERTY)
}
public Building getBuilding() {
return building;
}
public Integer getId() {
return id;
}
public String getNumber() {
return number;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(getNumber()).append(getBuilding().getId()).toHashCode();
}
public void setCapacity(Integer capacity) {
this.capacity = capacity;
}
//no setters for number, building nor id
}
Bu listeye eklemek için diğer öneriler hoş geldiniz daha vardır ...
GÜNCELLEME
Bu makaleyi okuduğumdan beri , eq / hC uygulama yöntemimi uyarladım:
- değişmez basit bir iş anahtarı varsa: bunu kullanın
- diğer tüm durumlarda: bir uuid kullanın
final
(pasörlerin yokluğuna bakarak, siz de yaparsınız).
notNull
geliyor?