So legen Sie mit dem Ruhezustand einen Standardwert für die Entitätseigenschaft fest

Antworten:

185

Wenn Sie einen echten Datenbankstandardwert wünschen, verwenden Sie columnDefinition:

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

Beachten Sie, dass die Zeichenfolge in columnDefinitiondatenbankabhängig ist. Wenn Sie diese Option auswählen, müssen Sie sie auch verwenden dynamic-insert, sodass beim Einfügen Hibernatekeine Spalten mit nullWerten enthalten sind. Andernfalls ist es irrelevant, über Standard zu sprechen.

Wenn Sie jedoch keinen Standardwert für die Datenbank, sondern nur einen Standardwert in Ihrem Java-Code möchten, initialisieren Sie Ihre Variable einfach so: private Integer myColumn = 100;

Petar Minchev
quelle
6
Mit Anmerkungen: @ org.hibernate.annotations.Entity (dynamicInsert = true)
Homaxto
9
Derzeit org.hibernate.annotations.Entityist veraltet. @DynamicInsertStattdessen sollte eine Anmerkung verwendet werden.
Jannis
1
Ich würde die Verwendung von columnDefinition für diese Situation nicht empfehlen. Dies ist nicht von einer Datenbank auf eine andere portierbar, und Sie müssen die spezifische SQL-Sprache Ihres Servers kennen.
pdem
@DynamicInsert muss der Datenbank-Pojo-Klasse hinzugefügt werden.
Reaz Murshed
3
Ich würde empfehlen, @ColumnDefault anstelle von columnDefinition zu verwenden, da es datenbankunabhängiger ist. Docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/…
jalsh
35

Sie können eine @PrePersistAnotation verwenden und den Standardwert in der Phase vor der Persistenz festlegen.

Sowas in der Art:

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

Diese Methode hängt nicht vom Datenbanktyp / der Datenbankversion unter dem Ruhezustand ab. Der Standardwert wird festgelegt, bevor das Zuordnungsobjekt beibehalten wird.

dbricman
quelle
Vorausgesetzt, setMyPropertydas wird von Ihrem Beispiel nicht verwendet. Warum schließen Sie es ein?
EndermanAPM
Ich gebe nur das Beispiel von Annotationen im Ruhezustand für die Standard-Java-Eigenschaft (private Variable mit öffentlichen get / set-Methoden). Ich habe einen Fehler bemerkt und korrigiert ... Der String-Typ der Set-Methode argumet fehlte.
Dbricman
30

Was ist mit dem Festlegen eines Standardwerts für das Feld?

private String _foo = "default";

//property here
public String Foo

Wenn sie einen Wert übergeben, wird dieser überschrieben. Andernfalls haben Sie einen Standardwert.

Tim Hoolihan
quelle
8
@michali: Die Rolle eines Standardwerts verhindert nicht, dass der Wert aktualisiert wird, oder?
Janusz Lenar
27

Verwenden Sie die Annotation für den Ruhezustand

@ColumnDefault("-1")
private Long clientId;
Mazen Embaby
quelle
Danke, es funktioniert. Aber ich musste die Tabelle neu erstellen.
Yamashiro Rion
1
Dies sollte die eigentliche Lösung sein. Die Verwendung von columnDefinition, wie in der aktuellen Antwort vorgeschlagen, ist ein Kinderspiel, und Sie müssen den Typ angeben. Die Annotation @ColumnDefault ist meiner Meinung nach viel einfacher.
Judos
7

Wenn Sie es in der Datenbank tun möchten:

Legen Sie den Standardwert in der Datenbank fest (SQL Server-Beispiel):

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

Zuordnen der Ruhezustandsdatei:

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

Siehe, der Schlüssel ist insert = "false" update = "false"

CSA
quelle
Es gibt ein Problem für Oracle: Wenn die Eigenschaft nicht null ist, ist ihr Wert NOCH der Standardwert. Nicht der tatsächliche Wert.
Youngzy
5

Eine Lösung besteht darin, Ihren Getter überprüfen zu lassen, ob der Wert, mit dem Sie arbeiten, null ist (oder der nicht initialisierte Status), und wenn er dem entspricht, geben Sie einfach Ihren Standardwert zurück:

public String getStringValue(){
     return (this.stringValue == null) ? "Default" : stringValue;
}
Ian Dallas
quelle
Ich verwende einen Mapper, der den Setter für mein Entity-Objekt aufruft. Gibt es einen Nachteil bei der Verwendung Ihres Code-Snippets sowohl für den Getter als auch für den Setter?
Eric Francis
4

Ich habe danach gesucht und viele Antworten auf den Standardwert für die Spalte gefunden. Wenn Sie den in der SQL-Tabelle definierten Standardwert verwenden möchten, verwenden Sie in @Column Annotation "insertable = false" . einsteckbar

@Column (name = columnName, length = lengthOfColumn, insertable = false)

Wenn Sie columnDefination verwenden, funktioniert die Annotation @Column möglicherweise nicht, da sie datenbankabhängig ist.

Garvit Bansal
quelle
Dies funktioniert hervorragend für Spalten wie "createdAt", in denen Sie immer den DB-Standard verwenden möchten. Vielen Dank!
Michal Filip
4

Verwenden Sie @ColumnDefault()Anmerkungen. Dies ist jedoch nur im Ruhezustand.

T3rm1
quelle
2

Bei der Arbeit mit Oracle habe ich versucht, einen Standardwert für eine Aufzählung einzufügen

Ich fand das Folgende am besten.

@Column(nullable = false)
@Enumerated(EnumType.STRING)
private EnumType myProperty = EnumType.DEFAULT_VALUE;
Bojan Petkovic
quelle
2

Sie können den Java-Klassenkonstruktor verwenden, um die Standardwerte festzulegen. Beispielsweise:

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

}
IKavanagh
quelle
2

So verwenden Sie den Standardwert aus einer beliebigen Tabellenspalte dann müssen Sie @DynamicInsertals wahr definieren , sonst definieren Sie nur @DynamicInsert. Weil der Ruhezustand standardmäßig als wahr gilt. Betrachten Sie als gegebenes Beispiel:

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

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

}
Dilip Verma
quelle
2

Standardwert der Entitätseigenschaft

Wenn Sie einen Standardwert für die Entitätseigenschaft festlegen möchten, können Sie das Entitätsfeld mit dem Standardwert initialisieren.

Sie können beispielsweise das Standardentitätsattribut wie createdOnfolgt auf die aktuelle Zeit festlegen :

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

Standardspaltenwert

Wenn Sie das DDL-Schema mit Hibernate generieren, obwohl dies nicht empfohlen wird, können Sie das columnDefinitionAttribut der JPA- @ColumnAnnotation wie folgt verwenden :

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

Die @GeneratedAnnotation wird benötigt, da wir Hibernate anweisen möchten, die Entität nach dem Löschen des Persistenzkontexts neu zu laden. Andernfalls wird der datenbankgenerierte Wert nicht mit dem speicherinternen Entitätsstatus synchronisiert.

Anstatt das zu verwenden columnDefinition, sollten Sie ein Tool wie Flyway verwenden und inkrementelle DDL-Migrationsskripte verwenden. Auf diese Weise legen Sie die DEFAULTSQL-Klausel in einem Skript und nicht in einer JPA-Annotation fest.

Weitere Informationen zur Verwendung der @GeneratedAnmerkung finden Sie in diesem Artikel .

Vlad Mihalcea
quelle
1

Ich arbeite mit Hibernate 5 und Postgres, und das hat bei mir funktioniert.

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

Wenn Sie den Standardwert in Bezug auf die Datenbank festlegen möchten, legen Sie einfach fest @Column( columnDefinition = "int default 1")

Wenn Sie jedoch einen Standardwert in Ihrer Java-App festlegen möchten, können Sie diesen für Ihr Klassenattribut wie folgt festlegen: private Integer attribute = 1;

Edgencio Da Calista
quelle
-3

Der obige Vorschlag funktioniert, jedoch nur, wenn die Annotation für die Getter-Methode verwendet wird. Wenn die Anmerkungen dort verwendet werden, wo das Mitglied deklariert ist, geschieht nichts.

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