วิธีการตั้งค่าคุณสมบัติเอนทิตีเริ่มต้นด้วย Hibernate


145

ฉันจะตั้งค่าเริ่มต้นในฟิลด์ Hibernate ได้อย่างไร


3
คุณกำลังใช้ไฟล์ XML หรือคำอธิบายประกอบอยู่หรือไม่?
Bruno

2
คำตอบด้านล่างให้โซลูชัน JPA เท่านั้นซึ่งถูกต้อง แต่สำหรับโซลูชัน Hibernate โปรดดูstackoverflow.com/questions/28107554/…คุณต้องใช้@ColumnDefault
pdem

คำตอบ:


185

หากคุณต้องการค่าเริ่มต้นของฐานข้อมูลจริงให้ใช้columnDefinition:

@Column(name = "myColumn", nullable = false, columnDefinition = "int default 100") 

ขอให้สังเกตว่าสตริงในcolumnDefinitionนั้นขึ้นอยู่กับฐานข้อมูล นอกจากนี้หากคุณเลือกตัวเลือกนี้คุณต้องใช้dynamic-insertดังนั้นจึงHibernateไม่รวมคอลัมน์ด้วยnullค่าในการแทรก มิฉะนั้นการพูดถึงค่าเริ่มต้นนั้นไม่เกี่ยวข้อง

แต่ถ้าคุณไม่ต้องการค่าเริ่มต้นของฐานข้อมูล แต่เป็นเพียงค่าเริ่มต้นในรหัส Java ของคุณเพียงแค่เริ่มต้นตัวแปรของคุณเช่นนั้น - private Integer myColumn = 100;


6
ด้วยคำอธิบายประกอบ: @ org.hibernate.annotations.Entity (dynamicInsert = true)
homaxto

9
ปัจจุบันorg.hibernate.annotations.Entityเลิกใช้แล้ว @DynamicInsertควรใช้คำอธิบายประกอบแทน
jannis

1
ฉันจะไม่แนะนำให้ใช้ columnDefinition สำหรับสถานการณ์นี้ไม่สามารถพกพาจากฐานข้อมูลไปยังอีกและคุณจำเป็นต้องรู้ภาษา SQL เฉพาะของเซิร์ฟเวอร์ของคุณ
pdem

@DynamicInsert จำเป็นต้องเพิ่มในคลาส pojo ฐานข้อมูล
Reaz Murshed

3
ผมขอแนะนำให้ใช้ @ColumnDefault แทน columnDefinition มันเป็นฐานข้อมูลอิสระdocs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/...
jalsh

35

คุณสามารถใช้คำ@PrePersistอธิบายประกอบและตั้งค่าเริ่มต้นในขั้นตอนก่อนล่วงหน้า

อะไรแบบนั้น:

//... 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;
}

วิธีนี้ไม่ได้ขึ้นอยู่กับประเภท / รุ่นของฐานข้อมูลภายใต้การไฮเบอร์เนต ค่าเริ่มต้นถูกตั้งค่าก่อนที่จะคงอยู่วัตถุการทำแผนที่


ระบุsetMyPropertyว่าไม่ได้ใช้โดยตัวอย่างของคุณ ทำไมคุณรวมถึง?
EndermanAPM

ฉันแค่ให้ตัวอย่างของคำอธิบายประกอบจำศีลสำหรับคุณสมบัติ java มาตรฐาน (ตัวแปรส่วนตัวที่มีวิธีการ get / set สาธารณะ) ฉันสังเกตและแก้ไขข้อผิดพลาดหนึ่งข้อ ... ประเภทสตริงของชุดเมธอด argumet หายไป
dbricman

30

สิ่งที่เกี่ยวกับเพียงแค่การตั้งค่าเริ่มต้นสำหรับสนาม?

private String _foo = "default";

//property here
public String Foo

หากพวกเขาผ่านค่าจากนั้นมันจะถูกเขียนทับมิฉะนั้นคุณมีค่าเริ่มต้น


8
@michali: บทบาทของค่าเริ่มต้นไม่ได้ป้องกันไม่ให้ปรับปรุงค่าใช่หรือไม่
Janusz Lenar

27

ใช้คำอธิบายประกอบจำศีล

@ColumnDefault("-1")
private Long clientId;

ขอบคุณมันใช้งานได้ แต่ฉันต้องสร้างตารางใหม่
Yamashiro Rion

1
นี่ควรเป็นทางออกที่แท้จริงการใช้ columnDefinition ตามที่เสนอโดยคำตอบปัจจุบันคือความเร่งรีบและคุณต้องรวมประเภทไว้ด้วย คำอธิบายประกอบ @ColumnDefault นั้นง่ายกว่ามากในความคิดของฉัน
ยูโด

7

ถ้าคุณต้องการที่จะทำในฐานข้อมูล:

ตั้งค่าเริ่มต้นในฐานข้อมูล (ตัวอย่างเซิร์ฟเวอร์ sql):

ALTER TABLE [TABLE_NAME] ADD  CONSTRAINT [CONSTRAINT_NAME]  DEFAULT (newid()) FOR [COLUMN_NAME]

การทำแผนที่ไฟล์จำศีล:

    <hibernate-mapping ....
    ...    
    <property name="fieldName" column="columnName" type="Guid" access="field" not-null="false"  insert="false" update="false"  />
    ...

ดูว่ากุญแจคือ insert = "false" update = "false"


มีปัญหาสำหรับ Oracle: ถ้าคุณสมบัติไม่ใช่ค่า null ค่าของ STILL จะเป็นค่าเริ่มต้น ไม่ใช่มูลค่าที่แท้จริง
อายุน้อยกว่า

5

ทางออกหนึ่งคือการตรวจสอบทะเยอทะยานของคุณเพื่อดูว่าสิ่งที่คุณกำลังทำงานกับค่าใดเป็นโมฆะ (หรือสถานะที่ไม่ได้กำหนดค่าเริ่มต้น) และถ้ามันเท่ากับนั้นเพียงแค่คืนค่าเริ่มต้นของคุณ:

public String getStringValue(){
     return (this.stringValue == null) ? "Default" : stringValue;
}

ฉันใช้ mapper ที่เรียกตัวตั้งค่าบนวัตถุเอนทิตีของฉัน มีข้อเสียในการใช้ข้อมูลโค้ดของคุณทั้งบนตัวรับและตัวตั้งค่าหรือไม่
Eric Francis

4

ผมค้นหานี้และพบว่าหลายคำตอบค่าเริ่มต้นสำหรับ column.If คุณต้องการที่จะใช้ค่าเริ่มต้นที่กำหนดไว้ในตาราง SQL แล้วใน @column หมายเหตุการใช้"insertable = false" insertable

@Column (ชื่อ = columnName, length = lengthOfColumn, insertable = false)

หากคุณกำลังใช้ columnDefination มัน @ หมายเหตุประกอบคอลัมน์อาจไม่ทำงานเนื่องจากขึ้นอยู่กับฐานข้อมูล


สิ่งนี้ใช้งานได้ดีสำหรับคอลัมน์เช่น "createdAt" ซึ่งคุณต้องการใช้ค่าเริ่มต้นของฐานข้อมูลเสมอ ขอบคุณ!
Michal Filip

4

ใช้@ColumnDefault()คำอธิบายประกอบ นี่คือการไฮเบอร์เนตเท่านั้น


2

ทำงานกับ Oracle ฉันพยายามแทรกค่าเริ่มต้นสำหรับ Enum

ฉันพบสิ่งต่อไปนี้เพื่อให้ทำงานได้ดีที่สุด

@Column(nullable = false)
@Enumerated(EnumType.STRING)
private EnumType myProperty = EnumType.DEFAULT_VALUE;

2

คุณสามารถใช้ตัวสร้างคลาส Java เพื่อตั้งค่าเริ่มต้น ตัวอย่างเช่น:

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
...

}

2

หากต้องการใช้ค่าเริ่มต้นจากคอลัมน์ใด ๆ ของตาราง แล้วคุณจะต้องจำเป็นต้องกำหนด@DynamicInsertเป็นความจริงหรืออื่น ๆ @DynamicInsertคุณเพียงแค่กำหนด เพราะไฮเบอร์เนตใช้ค่าเริ่มต้นเป็นจริง พิจารณาเป็นตัวอย่างที่ได้รับ:

@AllArgsConstructor
@Table(name = "core_contact")
@DynamicInsert
public class Contact implements Serializable {

    @Column(name = "status", columnDefinition = "int default 100")
    private Long status;

}

2

ค่าคุณสมบัติเอนทิตีเริ่มต้น

หากคุณต้องการตั้งค่าคุณสมบัติเอนทิตีเริ่มต้นจากนั้นคุณสามารถเริ่มต้นฟิลด์เอนทิตีโดยใช้ค่าเริ่มต้น

ตัวอย่างเช่นคุณสามารถตั้งค่าcreatedOnแอตทริบิวต์เอนทิตีเริ่มต้นเป็นเวลาปัจจุบันเช่นนี้:

@Column(
    name = "created_on"
)
private LocalDateTime createdOn = LocalDateTime.now();

ค่าคอลัมน์เริ่มต้น

หากคุณกำลังสร้างสกีมา DDL ด้วย Hibernate แม้ว่าจะไม่แนะนำก็ตามคุณสามารถใช้แอcolumnDefinitionททริบิวต์ของ@ColumnคำอธิบายประกอบJPA ได้เช่นนี้

@Column(
    name = "created_on", 
    columnDefinition = "DATETIME(6) DEFAULT CURRENT_TIMESTAMP"
)
@Generated(GenerationTime.INSERT)
private LocalDateTime createdOn;

@Generatedคำอธิบายประกอบเป็นสิ่งจำเป็นเพราะเราต้องการที่จะสั่ง Hibernate เพื่อโหลดกิจการหลังจากที่บริบทคงทนแดงมิฉะนั้นค่าฐานข้อมูลที่สร้างขึ้นจะไม่ตรงกับที่อยู่ในหน่วยความจำสถานะนิติบุคคล

แทนที่จะใช้columnDefinitionคุณจะดีกว่าการใช้เครื่องมือเช่น Flyway และใช้สคริปต์การย้ายข้อมูลส่วนเพิ่ม DDL ด้วยวิธีนี้คุณจะตั้งค่าส่วนDEFAULTคำสั่ง SQL ในสคริปต์แทนที่จะเป็นคำอธิบายประกอบ JPA

สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการใช้@Generatedคำอธิบายประกอบให้ตรวจสอบบทความนี้



1

ฉันกำลังทำงานกับ Hibernate 5 และ Postgres และสิ่งนี้ได้ผลกับฉัน

@Column(name = "ACCOUNT_TYPE", ***nullable***=false, columnDefinition="varchar2 default 'END_USER'")
@Enumerated(EnumType.STRING)
private AccountType accountType;

0

หากคุณต้องการตั้งค่าเริ่มต้นในแง่ของฐานข้อมูลเพียงแค่ตั้งค่า @Column( columnDefinition = "int default 1")

แต่ถ้าสิ่งที่คุณตั้งใจจะตั้งค่าเริ่มต้นในแอป java ของคุณคุณสามารถตั้งค่าในแอตทริบิวต์ class ของคุณเช่นนี้: private Integer attribute = 1;


-3

ข้อเสนอแนะดังกล่าวใช้งานได้ แต่เฉพาะในกรณีที่ใช้คำอธิบายประกอบในวิธี getter หากมีการใช้คำอธิบายประกอบที่สมาชิกประกาศจะไม่มีอะไรเกิดขึ้น

public String getStringValue(){
     return (this.stringValue == null) ? "Default" : stringValue;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.