Hazırda Beklet alanında varsayılan bir değeri nasıl belirlerim?
@ColumnDefault
Hazırda Beklet alanında varsayılan bir değeri nasıl belirlerim?
@ColumnDefault
Yanıtlar:
Gerçek bir veritabanı varsayılan değeri istiyorsanız, şunu kullanın columnDefinition
:
@Column(name = "myColumn", nullable = false, columnDefinition = "int default 100")
İçindeki dizenin columnDefinition
veritabanına bağlı olduğuna dikkat edin . Ayrıca bu seçeneği seçerseniz, kullanmanız gerekir dynamic-insert
, bu nedenle Hibernate
eklemede null
değerleri olan sütunları dahil etmeyin . Aksi takdirde temerrütten bahsetmek alakasızdır.
Ancak veritabanı varsayılan değerini istemiyorsanız, ancak Java kodunuzda yalnızca varsayılan bir değer istiyorsanız, değişkeninizi bu şekilde başlatmanız yeterlidir - private Integer myColumn = 100;
org.hibernate.annotations.Entity
kullanımdan kaldırılmıştır. @DynamicInsert
Onun yerine ek açıklama kullanılmalıdır.
@PrePersist
Anotasyon kullanabilir ve kalıcılık öncesi aşamada varsayılan değeri ayarlayabilirsiniz.
Bunun gibi bir şey:
//... some code
private String myProperty;
//... some code
@PrePersist
public void prePersist() {
if(myProperty == null) //We set default value in case if the value is not set yet.
myProperty = "Default value";
}
// property methods
@Column(nullable = false) //restricting Null value on database level.
public String getMyProperty() {
return myProperty;
}
public void setMyProperty(String myProperty) {
this.myProperty= myProperty;
}
Bu yöntem, Hazırda Bekletme altındaki veritabanı türüne / sürümüne bağlı değildir. Eşleme nesnesini sürdürmeden önce varsayılan değer ayarlanır.
setMyProperty
Sizin örneğiniz tarafından kullanılmadığı göz önüne alındığında . Neden dahil ediyorsunuz?
hazırda bekletme açıklamasını kullan
@ColumnDefault("-1")
private Long clientId;
alan için varsayılan bir değer belirlemeye ne dersiniz?
private String _foo = "default";
//property here
public String Foo
eğer bir değer geçerlerse, üzerine yazılır, aksi takdirde bir varsayılanınız olur.
Veritabanında yapmak istiyorsanız:
Veritabanında varsayılan değeri ayarlayın (sql sunucu örneği):
ALTER TABLE [TABLE_NAME] ADD CONSTRAINT [CONSTRAINT_NAME] DEFAULT (newid()) FOR [COLUMN_NAME]
Hazırda bekletme dosyası eşleniyor:
<hibernate-mapping ....
...
<property name="fieldName" column="columnName" type="Guid" access="field" not-null="false" insert="false" update="false" />
...
Bakın, anahtar insert = "false" update = "false"
Çözümlerden biri, alıcınızın çalıştığınız değerin boş olup olmadığını (veya başlatılmamış durumu ne olursa olsun) kontrol etmesini sağlamaktır ve buna eşitse, varsayılan değerinizi döndürmeniz yeterlidir:
public String getStringValue(){
return (this.stringValue == null) ? "Default" : stringValue;
}
Bunu aradım ve sütun için varsayılan değere birçok yanıt buldum. SQL Tablosunda tanımlanan varsayılan değeri kullanmak istiyorsanız @ Sütun Ek Açıklamasında " insertable = false" kullanın . sokulabilir
@Column (ad = sütunAdı, uzunluk = uzunlukOfColumn, eklenebilir = yanlış)
ColumnDefination kullanıyorsanız, @Column ek açıklaması Veritabanına bağlı olduğu için çalışmayabilir.
Varsayılan bir varlık özelliği değeri ayarlamak istiyorsanız, o zaman varlık alanını varsayılan değeri kullanarak başlatabilirsiniz.
Örneğin, varsayılan createdOn
varlık özniteliğini şu şekilde geçerli zamana ayarlayabilirsiniz :
@Column(
name = "created_on"
)
private LocalDateTime createdOn = LocalDateTime.now();
DDL şemasını JPA ve Hazırda Bekletme ile oluşturuyorsanız, bu önerilmese columnDefinition
de, JPA @Column
ek açıklamasının özniteliğini şu şekilde kullanabilirsiniz :
@Column(
name = "created_on",
columnDefinition = "DATETIME(6) DEFAULT CURRENT_TIMESTAMP"
)
@Generated(GenerationTime.INSERT)
private LocalDateTime createdOn;
@Generated
Biz Sebat Bağlam kızardı sonra, aksi takdirde, veritabanı tarafından oluşturulan değer bellek varlık durumuyla senkronize edilmez varlık yeniden Hibernate talimat istiyorum, çünkü açıklama gereklidir.
Kullanmak yerine columnDefinition
Flyway gibi bir araç kullanmanız ve DDL artımlı geçiş komut dosyalarını kullanmanız daha iyi olur. Bu şekilde, DEFAULT
SQL yan tümcesini bir JPA ek açıklaması yerine bir komut dosyasında ayarlarsınız .
@Generated
Ek açıklamayı kullanma hakkında daha fazla ayrıntı için bu makaleye göz atın .
Hazırda Bekletme ile JPA kullanıyorsanız, @ColumnDefault
ek açıklamayı şu şekilde de kullanabilirsiniz :
@Column(name = "created_on")
@ColumnDefault(value="CURRENT_TIMESTAMP")
@Generated(GenerationTime.INSERT)
private LocalDateTime createdOn;
Hazırda Bekletme ile JPA kullanıyorsanız ve oluşturma zaman damgasını ayarlamak istiyorsanız, @ColumnDefault
ek açıklamayı şu şekilde kullanabilirsiniz :
@Column(name = "created_on")
@CreationTimestamp
private LocalDateTime createdOn;
@CreationTimestamp
Ek açıklamayı kullanma hakkında daha fazla ayrıntı için bu makaleye göz atın .
@GeneratedValue
yalnızca varlık tanımlayıcıları için kullanılabilir.
@GeneratedValue
yalnızca varlığın birincil anahtarı ve @Generated
ilkel değerler için çalışır. Ancak bir alt varlık veya benzeri ek açıklamaları olan yabancı anahtar için ne kullanmalıyım @OneToOne
? Çünkü bu durum için 2 ek açıklamadan hiçbiri benim için işe yaramıyor.
@DynamicInsert
varlıkta kullanarak
Herhangi bir tablo sütunundaki varsayılan değeri kullanmak için. o zaman @DynamicInsert
doğru olarak tanımlamanız gerekir, yoksa sadece tanımlarsınız @DynamicInsert
. Çünkü hazırda bekletme varsayılan olarak doğru kabul edilir. Verilen örnek olarak düşünün:
@AllArgsConstructor
@Table(name = "core_contact")
@DynamicInsert
public class Contact implements Serializable {
@Column(name = "status", columnDefinition = "int default 100")
private Long status;
}
Oracle ile çalışırken, Enum için varsayılan bir değer eklemeye çalışıyordum
Aşağıdakileri en iyi şekilde çalıştığını buldum.
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private EnumType myProperty = EnumType.DEFAULT_VALUE;
Varsayılan değerleri ayarlamak için java sınıfı yapıcısını kullanabilirsiniz. Örneğin:
public class Entity implements Serializable{
private Double field1
private Integer field2;
private T fieldN;
public Entity(){
this.field1=0.0;
this.field2=0;
...
this.fieldN= <your default value>
}
//Setters and Getters
...
}
<property name="age" type="integer">
<column name="age" not-null="false" default="null" />
</property>
Hibernate 5 ve postgres ile çalışıyorum ve bu benim için çalıştı.
@Column(name = "ACCOUNT_TYPE", ***nullable***=false, columnDefinition="varchar2 default 'END_USER'")
@Enumerated(EnumType.STRING)
private AccountType accountType;
Veritabanı açısından varsayılan değeri ayarlamak isterseniz, @Column( columnDefinition = "int default 1")
Ancak, niyet ettiğiniz şey java uygulamanızda varsayılan bir değer ayarlamaksa, bunu sınıf özniteliğinizde şu şekilde ayarlayabilirsiniz: private Integer attribute = 1;
Bir alt varlık içeren bir varlığımız olduğunu varsayalım.
Kullanılması insertable = false, updatable = false
yeni alt varlıkları yaratan ve varsayılan DBMS değerini önceki gelen varlık bulunanları engeller varlık. Ancak bununla ilgili sorun, her zaman varsayılan değeri kullanmak zorunda olmamız veya varlığın varsayılan olmayan başka bir alt varlık içermesine ihtiyacımız varsa, bu ek açıklamaları çalışma zamanında olarak değiştirmeye çalışmalıyız insertable = true, updatable = true
, böylece iyi bir yol gibi görünüyor.
Alt varlığın içinde, tüm sütunlarda kullanmak daha mantıklıysa, insertable = false, updatable = false
böylece kullandığımız yöntemden bağımsız olarak artık alt varlık oluşturulmaz ( @DynamicInsert
bununla birlikte gerekli olmazdı)
Varsayılan bir değerin eklenmesi, yapıcı veya ayarlayıcı kullanılarak Varsayılan varlık özelliği değeri gibi çeşitli şekillerde yapılabilir . JPA'yı columnDefinition ile kullanmak gibi diğer yolların dezavantajı, varsayılan olarak bir boş değer eklemesidir ve DBMS'nin varsayılan değerinden önce gelmez.
Ancak kullanarak @DynamicInsert
, varsayılan değerine sahip bir alt varlık eklemek istediğimizde db'ye bir boş değer göndermekten kaçınırız ve karşılığında varsayılan değerden farklı değerlere sahip alt varlıkların eklenmesine izin veririz.
Ekleme için, hazırlanan sql deyiminde yalnızca boş olmayan sütunlara atıfta bulunulduğunda bu varlık dinamik sql oluşturmayı mı kullanmalı?
Aşağıdaki ihtiyaçlar göz önüne alındığında:
DBMS : PostgreSQL | Dil : Kotlin
@Entity
@Table(name = "entity")
@DynamicInsert
data class EntityTest(
@Id @GeneratedValue @Column(name = "entity_uuid") val entityUUID: UUID? = null,
@OneToOne(cascade = [CascadeType.ALL])
@JoinColumn(name = "subentity_uuid", referencedColumnName = "subentity_uuid")
var subentityTest: SubentityTest? = null
) {}
@Entity
@Table(name = "subentity")
data class SubentityTest(
@Id @GeneratedValue @Column(name = "subentity_uuid", insertable = false, updatable = false) var subentityUUID: UUID? = null,
@Column(insertable = false, updatable = false) var name: String,
) {
constructor() : this(name = "")
}
Ve değer, veritabanında varsayılan olarak ayarlanır:
alter table entity alter column subentity_uuid set default 'd87ee95b-06f1-52ab-83ed-5d882ae400e6'::uuid;
GL
Yukarıdaki öneri işe yarar, ancak yalnızca ek açıklama alıcı yönteminde kullanılıyorsa. Üyenin ilan edildiği yerde ek açıklamalar kullanılırsa hiçbir şey olmaz.
public String getStringValue(){
return (this.stringValue == null) ? "Default" : stringValue;
}