जेपीए में कॉलम के लिए डिफ़ॉल्ट मान सेट करना


245

क्या जेपीए में कॉलम के लिए एक डिफ़ॉल्ट मान सेट करना संभव है, और यदि, यह एनोटेशन का उपयोग कैसे किया जाता है?


वहाँ जेपीए sepcification में है, जहां मैं एक कॉलम के लिए डिफ़ॉल्ट मान को दूसरे कॉलम के लिए मान के रूप में रख सकता हूं, क्योंकि मैं चाहता हूं कि यह छिपा हो
shareef

3
संबंधित: हाइबरनेट में @ org.hibernate.annotations.olumnDefault ("foo")
Ondra žižka

जवाबों:


230

वास्तव में यह जेपीए में संभव है, हालांकि एनोटेशन की columnDefinitionसंपत्ति का उपयोग करके हैक का एक छोटा सा @Columnउदाहरण के लिए:

@Column(name="Price", columnDefinition="Decimal(10,2) default '100.00'")

3
10 पूर्णांक भाग है, और 2 संख्या का दशमलव भाग है: 1234567890.12 एक समर्थित संख्या होगी।
नाथन फेगर

23
ध्यान दें, यह कॉलमडिफ़िनिशन आवश्यक रूप से डेटाबेस स्वतंत्र नहीं है, और निश्चित रूप से जावा में डेटाटाइप को स्वचालित रूप से बंधा नहीं है।
नाथन फेगर

47
एक अशक्त क्षेत्र के साथ एक इकाई बनाने और इसे जारी रखने के बाद, आपके पास इसमें निर्धारित मूल्य नहीं होगा। समाधान नहीं ...
पास्कल थिवेंट

18
कोई @NathanFeger, 10 लंबाई और 2 दशमलव भाग है। तो 1234567890.12 एक समर्थित संख्या नहीं होगी, लेकिन 12345678.90 वैध है।
GPrimola

4
insertable=falseयदि स्तंभ अशक्त है (और अनावश्यक स्तंभ तर्क से बचने के लिए) आपको इसकी आवश्यकता होगी ।
Eckes

314

आप निम्न कार्य कर सकते हैं:

@Column(name="price")
private double price = 0.0;

वहाँ! आपने डिफ़ॉल्ट मान के रूप में शून्य का उपयोग किया है।

ध्यान दें कि यदि आप केवल इस एप्लिकेशन से डेटाबेस तक पहुंच रहे हैं तो यह आपकी सेवा करेगा। यदि अन्य एप्लिकेशन भी डेटाबेस का उपयोग करते हैं, तो आपको कैमरून के कॉलमडिफ़िनेशन एनोटेशन विशेषता या किसी अन्य तरीके से डेटाबेस से इस चेक को बनाना चाहिए ।


38
यह करने का सही तरीका है यदि आप चाहते हैं कि आपकी इकाइयाँ डालने के बाद सही मान लें। +1
पास्कल थिवेंट

16
मॉडल श्रेणी में एक अशक्त विशेषता (एक गैर-आदिम प्रकार) का डिफ़ॉल्ट मान सेट करना मानदंड क्वेरी को तोड़ देगा Exampleजो खोज के लिए एक प्रोटोटाइप के रूप में किसी ऑब्जेक्ट का उपयोग करता है । एक डिफ़ॉल्ट मान सेट करने के बाद, एक हाइबरनेट उदाहरण क्वेरी अब संबंधित कॉलम को अनदेखा नहीं करेगी जहां पहले यह इसे अनदेखा करेगा क्योंकि यह शून्य था। एक बेहतर तरीका यह है कि हाइबरनेट save()या इंवेट करने से पहले सभी डिफॉल्ट वैल्यू को सेट किया जाए update()। यह बेहतर डेटाबेस के व्यवहार की नकल करता है जो एक पंक्ति को बचाता है जब डिफ़ॉल्ट मान सेट करता है।
डेरेक महार

1
@ गृह: यह डिफ़ॉल्ट मान सेट करने का सही तरीका है, जब आप मापदंड प्रश्नों का उपयोग कर रहे हैं, जो खोज के लिए एक प्रोटोटाइप के रूप में एक उदाहरण का उपयोग करते हैं।
डेरेक महार

12
यह सुनिश्चित नहीं करता है कि डिफ़ॉल्ट गैर आदिम प्रकार ( nullउदाहरण के लिए सेटिंग ) के लिए सेट है । का उपयोग करना @PrePersistऔर @PreUpdateएक बेहतर विकल्प imho है।
जैस्पर

3
कॉलम के लिए डिफ़ॉल्ट मान निर्दिष्ट करने का यह सही तरीका है। columnDefinitionसंपत्ति डेटाबेस-स्वतंत्र नहीं है और @PrePersistडालने से पहले आपकी सेटिंग को ओवरराइड करती है, "डिफ़ॉल्ट मान" कुछ और है, डिफ़ॉल्ट मूल्य का उपयोग तब किया जाता है जब मूल्य स्पष्ट रूप से सेट नहीं किया जाता है।
उत्कु irzdemir

110

एक अन्य दृष्टिकोण javax.persistence.PrePersist का उपयोग कर रहा है

@PrePersist
void preInsert() {
   if (this.createdTime == null)
       this.createdTime = new Date();
}

1
मैंने टाइमस्टैम्प को जोड़ने और अपडेट करने के लिए इस तरह के दृष्टिकोण का उपयोग किया। इसने बहुत अच्छा काम किया।
Spina

10
यह if (createdt != null) createdt = new Date();या कुछ नहीं होना चाहिए ? अभी, यह स्पष्ट रूप से निर्दिष्ट मूल्य को ओवरराइड करेगा, जो ऐसा लगता है कि यह वास्तव में डिफ़ॉल्ट नहीं है।
मैक्स नानसी

16
@ मोमनेसीif (createdt == null) createdt = new Date();
शेन

अगर क्लाइंट और डेटाबेस अलग-अलग टाइमज़ोन में हैं तो क्या इससे कोई फर्क पड़ेगा? मुझे लगता है कि "TIMESTAMP DEFAULT CURRENT_TIMESTAMP" जैसे कुछ का उपयोग करने से डेटाबेस सर्वर पर वर्तमान समय मिलेगा, और जावा कोड में "createt = new Date ()" को वर्तमान समय मिलेगा, लेकिन दो बार का उपयोग समान नहीं हो सकता है क्लाइंट एक अलग टाइमज़ोन में सर्वर से जुड़ रहा है।
FrustratedWithFormsDesigner

nullचेक जोड़ा गया ।
ओन्ड्रा kaसिका

49

2017 में, जेपीए 2.1 में अभी भी केवल वही @Column(columnDefinition='...')है जो आपने कॉलम की शाब्दिक एसक्यूएल परिभाषा को रखा है। जो काफी अप्रभावी है और आपको उस मामले के लिए जेपीए कार्यान्वयन के दृष्टिकोण के प्रकार, लघु-सर्कुलेटिंग जैसे अन्य पहलुओं की घोषणा करने के लिए मजबूर करता है।

हाइबरनेट हालांकि, यह है:

@Column(length = 4096, nullable = false)
@org.hibernate.annotations.ColumnDefault("")
private String description;

डीडीएल के माध्यम से संबद्ध कॉलम में आवेदन करने के लिए DEFAULT मान की पहचान करता है।

उस पर दो नोट:

1) गैर-मानक जाने से डरो मत। JBoss डेवलपर के रूप में काम करते हुए, मैंने कुछ विनिर्देश प्रक्रियाएँ देखी हैं। विनिर्देश मूल रूप से आधारभूत है कि दिए गए क्षेत्र में बड़े खिलाड़ी अगले दशक तक समर्थन करने के लिए प्रतिबद्ध हैं। यह सुरक्षा के लिए सही है, मैसेजिंग के लिए, ORM कोई अंतर नहीं है (हालाँकि JPA काफी कवर करता है)। एक डेवलपर के रूप में मेरा अनुभव यह है कि एक जटिल एप्लिकेशन में, जल्दी या बाद में आपको वैसे भी एक गैर-मानक एपीआई की आवश्यकता होगी। और @ColumnDefaultएक उदाहरण है जब यह एक गैर-मानक समाधान का उपयोग करने के नकारात्मक परिणामों से बचता है।

2) यह अच्छा है कि कैसे हर कोई @PrePersist या कंस्ट्रक्टर सदस्य आरंभीकरण करता है। लेकिन ऐसा नहीं है। थोक SQL अपडेट के बारे में कैसे? उन बयानों के बारे में कैसे जो कॉलम सेट नहीं करते हैं? DEFAULTइसकी भूमिका है और यह जावा वर्ग के सदस्य को आरंभीकृत करके प्रतिस्थापित करने योग्य नहीं है।


वाइबरफ्लाई 12 के लिए मैं हाइबरनेट-एनोटेशन के किस संस्करण का उपयोग कर सकता हूं, मैं इसके विशिष्ट संस्करण के साथ एक त्रुटि पकड़ता हूं? धन्यवाद अग्रिम!
फर्नांडो पाई

धन्यवाद ओन्द्रा। क्या 2019 में कोई और समाधान है?
एलन

1
@ शेयर स्टॉक में नहीं, दुख की बात है।
जॉइंटिंग सेप

13

जेपीए इसका समर्थन नहीं करता है और यदि यह किया जाता है तो यह उपयोगी होगा। कॉलमडिफ़िनिशन का उपयोग करना डीबी-विशिष्ट है और कई मामलों में स्वीकार्य नहीं है। कक्षा में एक डिफ़ॉल्ट सेट करना पर्याप्त नहीं है जब आप एक रिकॉर्ड को शून्य मान प्राप्त करते हैं (जो आमतौर पर तब होता है जब आप पुराने DBUnit परीक्षण फिर से चलाते हैं)। मैं यह क्या कर रहा हूँ:

public class MyObject
{
    int attrib = 0;

    /** Default is 0 */
    @Column ( nullable = true )
    public int getAttrib()

    /** Falls to default = 0 when null */
    public void setAttrib ( Integer attrib ) {
       this.attrib = attrib == null ? 0 : attrib;
    }
}

जावा ऑटो-बॉक्सिंग उस में बहुत मदद करता है।


बसनेवालों को गाली मत दो! वे एक वस्तु क्षेत्र में एक पैरामीटर सेट करने के लिए हैं। और कुछ नहीं! डिफ़ॉल्ट मान के लिए बेहतर कंस्ट्रक्टर का उपयोग करें।
रोलैंड

@ रोलांड सिद्धांत में अच्छा है, लेकिन हमेशा एक मौजूदा डेटाबेस से निपटने के दौरान काम नहीं करेगा जिसमें पहले से ही शून्य मान शामिल हैं जहां आपका एप्लिकेशन उन्हें नहीं करना चाहेगा। आपको पहले एक डेटाबेस रूपांतरण करने की आवश्यकता होगी जहां आप कॉलम को शून्य नहीं बनाते हैं और एक ही समय में एक समझदार डिफ़ॉल्ट सेट करते हैं, और फिर अन्य अनुप्रयोगों से बैकलैश से निपटते हैं जो यह मानते हैं कि यह वास्तव में अशक्त है (यदि आप हैं, तो डेटाबेस को संशोधित भी कर सकते हैं)।
jwenting

यदि यह #JPA की बात आती है और बसने / पाने वालों के लिए, उन्हें हमेशा शुद्ध सेटर / गेट्टर होना चाहिए, तो एक दिन आपके आवेदन में वृद्धि और वृद्धि हुई है और एक रखरखाव दुःस्वप्न बन गया है। बेस्ट सलाह यहाँ KISS (मैं, कोई समलैंगिक हूँ LOL) है।
रोलैंड

10

जब मैंने उसी समस्या को हल करने की कोशिश करते हुए इसे Google से ठोकर के रूप में देखा, तो मैं केवल उस समाधान में फेंकने जा रहा हूं जिसे मैंने पकाया है यदि कोई इसे उपयोगी पाता है।

मेरे दृष्टिकोण से इस समस्या का केवल 1 समाधान है - @PrePersist। यदि आप इसे @PrePersist में करते हैं, तो आप जाँच सकते हैं कि मान पहले से निर्धारित है या नहीं।


4
+1 - मैं निश्चित रूप से @PrePersistOP के usecase का विकल्प चुनूंगा। @Column(columnDefinition=...)बहुत सुंदर नहीं लगती।
पायोतर नाउकी

@PrePersist आपकी मदद नहीं करेगा यदि पहले से ही स्टोर में शून्य मान के साथ डेटा है। यह जादुई रूप से आपके लिए डेटाबेस रूपांतरण नहीं करेगा।
अक्टूबर

10
@Column(columnDefinition="tinyint(1) default 1")

मैंने सिर्फ इस मुद्दे का परीक्षण किया। यह ठीक काम करता है। संकेत के लिए धन्यवाद।


टिप्पणियों के बारे में:

@Column(name="price") 
private double price = 0.0;

यह डेटाबेस (निश्चित रूप से) में डिफ़ॉल्ट कॉलम मान सेट नहीं करता है


9
यह ऑब्जेक्ट स्तर पर ठीक काम नहीं करता है (आपको अपनी इकाई में सम्मिलित करने के बाद डेटाबेस डिफ़ॉल्ट मान नहीं मिलेगा)। जावा स्तर पर डिफ़ॉल्ट।
पास्कल थिवेंट

यह काम करता है (विशेष रूप से यदि आप डेटाबेस में सम्मिलित करने योग्य = गलत निर्दिष्ट करते हैं, लेकिन दुर्भाग्यपूर्ण तरीके से कैश्ड संस्करण ताज़ा नहीं किया जाता है (तब भी जब जेपीए तालिका और कॉलम का चयन नहीं करता है)। कम से कम हाइबरनेट के साथ नहीं: - / लेकिन यहां तक ​​कि अगर अतिरिक्त काम करेगा। राउंडट्रिप खराब है।
1

9

आप जावा को प्रतिबिंबित एपी का उपयोग कर सकते हैं:

    @PrePersist
    void preInsert() {
       PrePersistUtil.pre(this);
    }

यह आम है:

    public class PrePersistUtil {

        private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


        public static void pre(Object object){
            try {
                Field[] fields = object.getClass().getDeclaredFields();
                for(Field field : fields){
                    field.setAccessible(true);
                    if (field.getType().getName().equals("java.lang.Long")
                            && field.get(object) == null){
                        field.set(object,0L);
                    }else if    (field.getType().getName().equals("java.lang.String")
                            && field.get(object) == null){
                        field.set(object,"");
                    }else if (field.getType().getName().equals("java.util.Date")
                            && field.get(object) == null){
                        field.set(object,sdf.parse("1900-01-01"));
                    }else if (field.getType().getName().equals("java.lang.Double")
                            && field.get(object) == null){
                        field.set(object,0.0d);
                    }else if (field.getType().getName().equals("java.lang.Integer")
                            && field.get(object) == null){
                        field.set(object,0);
                    }else if (field.getType().getName().equals("java.lang.Float")
                            && field.get(object) == null){
                        field.set(object,0.0f);
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

2
मुझे यह समाधान पसंद है, लेकिन कमजोरी का एक बिंदु है, मुझे लगता है कि यह महत्वपूर्ण जाँच होगी कि क्या कॉलम अशक्त है या सेट डिफ़ॉल्ट मान से पहले नहीं है।
लुइस कार्लोस

यदि आप चाहें, से कोड डालने Field[] fields = object.getClass().getDeclaredFields();में for()ठीक है, भी हो सकता है। और finalअपने पैरामीटर / जोड़ अपवादों को भी जोड़ें क्योंकि आप objectदुर्घटना से संशोधित नहीं होना चाहते हैं । इसके अलावा पर एक जाँच जोड़ने null: if (null == object) { throw new NullPointerException("Parameter 'object' is null"); }। यह सुनिश्चित करता है कि object.getClass()आह्वान करना सुरक्षित है और ट्रिगर नहीं करता है NPE। इसका कारण आलसी प्रोग्रामर द्वारा गलतियों से बचना है। ;-)
रोलैंड

7

मैं उपयोग columnDefinitionकरता हूं और यह बहुत अच्छा काम करता है

@Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

private Date createdDate;

6
ऐसा लगता है कि यह आपके जेपीए कार्यान्वयन विक्रेता को विशिष्ट बनाता है।
उडो हेल्ड

यह केवल DDL विक्रेता को विशिष्ट बनाता है। लेकिन आपके पास सबसे अधिक संभावना है कि विक्रेता विशिष्ट DDL हैक्स वैसे भी है .. हालाँकि जैसा कि ऊपर उल्लेख किया गया है (तब भी जब डालने योग्य = गलत) डीबी में दिखाई देता है, लेकिन सत्र के इकाई कैश में नहीं (कम से कम हाइबरनेट में नहीं)।
Eckes

7

आप कॉलम एनोटेशन के साथ ऐसा नहीं कर सकते। मुझे लगता है कि ऑब्जेक्ट बनाते समय डिफ़ॉल्ट मान सेट करने का एकमात्र तरीका है। हो सकता है कि डिफ़ॉल्ट कंस्ट्रक्टर ऐसा करने के लिए सही जगह हो।


अछा सुझाव। अफसोस की बात है कि आसपास कोई जेनेरिक एनोटेशन या विशेषता नहीं है @Column। और मुझे सेट की जा रही टिप्पणियों (जावा सिद्धांत से लिया गया) भी याद आती है।
रोलैंड

5

मेरे मामले में, मैंने एक नया एनोटेशन शुरू करने के लिए हाइबरनेट-कोर सोर्स कोड को संशोधित किया है @DefaultValue:

commit 34199cba96b6b1dc42d0d19c066bd4d119b553d5
Author: Lenik <xjl at 99jsj.com>
Date:   Wed Dec 21 13:28:33 2011 +0800

    Add default-value ddl support with annotation @DefaultValue.

diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DefaultValue.java b/hibernate-core/src/main/java/org/hibernate/annotations/DefaultValue.java
new file mode 100644
index 0000000..b3e605e
--- /dev/null
+++ b/hibernate-core/src/main/java/org/hibernate/annotations/DefaultValue.java
@@ -0,0 +1,35 @@
+package org.hibernate.annotations;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+
+/**
+ * Specify a default value for the column.
+ *
+ * This is used to generate the auto DDL.
+ *
+ * WARNING: This is not part of JPA 2.0 specification.
+ *
+ * @author 谢继雷
+ */
+@java.lang.annotation.Target({ FIELD, METHOD })
+@Retention(RUNTIME)
+public @interface DefaultValue {
+
+    /**
+     * The default value sql fragment.
+     *
+     * For string values, you need to quote the value like 'foo'.
+     *
+     * Because different database implementation may use different 
+     * quoting format, so this is not portable. But for simple values
+     * like number and strings, this is generally enough for use.
+     */
+    String value();
+
+}
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java
index b289b1e..ac57f1a 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3Column.java
@@ -29,6 +29,7 @@ import org.hibernate.AnnotationException;
 import org.hibernate.AssertionFailure;
 import org.hibernate.annotations.ColumnTransformer;
 import org.hibernate.annotations.ColumnTransformers;
+import org.hibernate.annotations.DefaultValue;
 import org.hibernate.annotations.common.reflection.XProperty;
 import org.hibernate.cfg.annotations.Nullability;
 import org.hibernate.mapping.Column;
@@ -65,6 +66,7 @@ public class Ejb3Column {
    private String propertyName;
    private boolean unique;
    private boolean nullable = true;
+   private String defaultValue;
    private String formulaString;
    private Formula formula;
    private Table table;
@@ -175,7 +177,15 @@ public class Ejb3Column {
        return mappingColumn.isNullable();
    }

-   public Ejb3Column() {
+   public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    public Ejb3Column() {
    }

    public void bind() {
@@ -186,7 +196,7 @@ public class Ejb3Column {
        }
        else {
            initMappingColumn(
-                   logicalColumnName, propertyName, length, precision, scale, nullable, sqlType, unique, true
+                   logicalColumnName, propertyName, length, precision, scale, nullable, sqlType, unique, defaultValue, true
            );
            log.debug( "Binding column: " + toString());
        }
@@ -201,6 +211,7 @@ public class Ejb3Column {
            boolean nullable,
            String sqlType,
            boolean unique,
+           String defaultValue,
            boolean applyNamingStrategy) {
        if ( StringHelper.isNotEmpty( formulaString ) ) {
            this.formula = new Formula();
@@ -217,6 +228,7 @@ public class Ejb3Column {
            this.mappingColumn.setNullable( nullable );
            this.mappingColumn.setSqlType( sqlType );
            this.mappingColumn.setUnique( unique );
+           this.mappingColumn.setDefaultValue(defaultValue);

            if(writeExpression != null && !writeExpression.matches("[^?]*\\?[^?]*")) {
                throw new AnnotationException(
@@ -454,6 +466,11 @@ public class Ejb3Column {
                    else {
                        column.setLogicalColumnName( columnName );
                    }
+                   DefaultValue _defaultValue = inferredData.getProperty().getAnnotation(DefaultValue.class);
+                   if (_defaultValue != null) {
+                       String defaultValue = _defaultValue.value();
+                       column.setDefaultValue(defaultValue);
+                   }

                    column.setPropertyName(
                            BinderHelper.getRelativePath( propertyHolder, inferredData.getPropertyName() )
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
index e57636a..3d871f7 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
@@ -423,6 +424,7 @@ public class Ejb3JoinColumn extends Ejb3Column {
                getMappingColumn() != null ? getMappingColumn().isNullable() : false,
                referencedColumn.getSqlType(),
                getMappingColumn() != null ? getMappingColumn().isUnique() : false,
+               null, // default-value
                false
        );
        linkWithValue( value );
@@ -502,6 +504,7 @@ public class Ejb3JoinColumn extends Ejb3Column {
                getMappingColumn().isNullable(),
                column.getSqlType(),
                getMappingColumn().isUnique(),
+               null, // default-value
                false //We do copy no strategy here
        );
        linkWithValue( value );

खैर, यह एक हाइबरनेट-केवल समाधान है।


2
हालांकि मैं उन लोगों के प्रयास की सराहना करता हूं जो स्रोत परियोजना को खोलने में सक्रिय रूप से योगदान करते हैं, मैंने इस उत्तर को अस्वीकार कर दिया क्योंकि जेपीए किसी भी OR / M के शीर्ष पर एक मानक जावा विनिर्देश है, ओपी ने डिफ़ॉल्ट मूल्यों और आपके पैच कार्यों को निर्दिष्ट करने के लिए एक जेपीए तरीका पूछा। केवल हाइबरनेट के लिए। यदि यह NHibernate था, जिसमें दृढ़ता के लिए कोई सुपर-पार्टिशन विनिर्देश नहीं है (MS EF द्वारा समर्थित NPA भी नहीं है), तो मैंने इस तरह के पैच को उकेरा होगा। सच्चाई यह है कि जेपीए ओआरएम (एक उदाहरण: कोई माध्यमिक सूचकांक) की आवश्यकताओं की तुलना में काफी सीमित है। वैसे भी प्रयास करने के लिए यश
usr-local-os

क्या यह रखरखाव का मुद्दा नहीं बनता है? जब भी हाइबरनेट उन्नयन या हर ताज़ा स्थापना पर इन परिवर्तनों को फिर से करने की आवश्यकता होगी?
user1242321

चूँकि सवाल JPA के बारे में है, और हाइबरनेट का भी उल्लेख नहीं किया गया है, इस सवाल का जवाब नहीं है
नील स्टॉकटन

5
  1. @Column(columnDefinition='...') डेटा सम्मिलित करते समय डेटाबेस में डिफ़ॉल्ट बाधा निर्धारित करने पर काम नहीं करता है।
  2. आपको एनोटेशन से बनाने insertable = falseऔर निकालने की आवश्यकता है columnDefinition='...', फिर डेटाबेस स्वचालित रूप से डेटाबेस से डिफ़ॉल्ट मान सम्मिलित करेगा।
  3. उदाहरण के लिए, जब आप डेटाबेस में डिफ़ॉल्ट रूप से नर लिंग निर्धारित करते हैं।
  4. आपको बस insertable = falseहाइबरनेट / जेपीए में जोड़ने की आवश्यकता है , यह काम करेगा।

अच्छा उत्तर। और यहाँ समझाया-
डालने

और एक अच्छा विकल्प नहीं है, अगर आप कभी-कभी इसका मूल्य निर्धारित करना चाहते हैं।
शिह झांग

@ शीशी झंग का उपयोग कर मुझे मूल्य निर्धारित नहीं करने देता?
fvildoso

3
@PrePersist
void preInsert() {
    if (this.dateOfConsent == null)
        this.dateOfConsent = LocalDateTime.now();
    if(this.consentExpiry==null)
        this.consentExpiry = this.dateOfConsent.plusMonths(3);
}

मेरे मामले में लोकल डेटाइम मैं का इस्तेमाल होने के कारण, यह विक्रेता की स्वतंत्रता के कारण अनुशंसित है


2

न तो JPA और न ही हाइबरनेट एनोटेशन डिफ़ॉल्ट स्तंभ मान की धारणा का समर्थन करते हैं। इस सीमा तक वर्कअराउंड के रूप में, आप हाइबरनेट save()या update()सत्र पर आने से ठीक पहले सभी डिफ़ॉल्ट मान सेट करें । यह निकटता से संभव है (डिफॉल्ट मान सेट करने के लिए हाइबरनेट की कमी) डेटाबेस के व्यवहार की नकल करता है जो एक तालिका में एक पंक्ति को सहेजते समय डिफ़ॉल्ट मान सेट करता है।

मॉडल वर्ग में डिफ़ॉल्ट मान सेट करने के विपरीत, जैसा कि यह वैकल्पिक उत्तर बताता है, यह दृष्टिकोण यह भी सुनिश्चित करता है कि मानदंड क्वेरी जो Exampleखोज के लिए एक प्रोटोटाइप के रूप में किसी ऑब्जेक्ट का उपयोग करती है, पहले की तरह काम करती रहेगी। जब आप मॉडल श्रेणी में एक अशक्त विशेषता (एक गैर-आदिम प्रकार) का डिफ़ॉल्ट मान सेट करते हैं, तो एक हाइबरनेट क्वेरी-बाय-उदाहरण अब संबंधित स्तंभ को अनदेखा नहीं करेगा जहां पहले यह इसे अनदेखा करेगा क्योंकि यह अशक्त था।


पिछले समाधान में लेखक ने ColumnDefault ("") का
उल्लेख किया है

@ nikolai.serdiuk कि इस उत्तर के लिखे जाने के बाद ColumnDefault एनोटेशन को जोड़ा गया था। 2010 में यह सही था, ऐसा कोई एनोटेशन नहीं था (वास्तव में कोई एनोटेशन नहीं थे, केवल xml कॉन्फ़िगरेशन था)।
jwenting

1

यह जेपीए में संभव नहीं है।

यहां आप कॉलम एनोटेशन के साथ क्या कर सकते हैं: http://java.sun.com/javaee/5/docs/api/javax/persistence/Column.html


1
डिफ़ॉल्ट मान निर्दिष्ट करने में सक्षम नहीं होने के कारण जेपीए एनोटेशन की एक गंभीर कमी प्रतीत होती है।
डेरेक महार

2
JDO इसकी ORM परिभाषा में इसकी अनुमति देता है, इसलिए JPA को इसे शामिल करना चाहिए ... एक दिन
user383680

आप निश्चित रूप से इसे कर सकते हैं, कॉलमडिफाइनमेंट विशेषता के साथ, जैसा कि कैमरन पोप ने उत्तर दिया था।
इंटेलीडाटा

@DerekMahar यह जेपीए विनिर्देश में एकमात्र कमी नहीं है। यह एक अच्छा विनिर्देश है, लेकिन यह सही नहीं है
jwenting

1

यदि आप एक डबल का उपयोग कर रहे हैं, तो आप निम्नलिखित का उपयोग कर सकते हैं:

@Column(columnDefinition="double precision default '96'")

private Double grolsh;

हाँ यह डीबी विशिष्ट है।


0

आप डेटाबेस डिज़ाइनर में डिफ़ॉल्ट मान को परिभाषित कर सकते हैं, या जब आप तालिका बनाते हैं। उदाहरण के लिए SQL सर्वर में आप दिनांक फ़ील्ड ( getDate()) के डिफ़ॉल्ट वॉल्ट सेट कर सकते हैं । insertable=falseअपने कॉलम की परिभाषा के अनुसार उपयोग करें । जेपीए आवेषण पर उस कॉलम को निर्दिष्ट नहीं करेगा और डेटाबेस आपके लिए मूल्य उत्पन्न करेगा।


-2

insertable=falseआपको @Columnएनोटेशन की जरूरत है । तब JPA डेटाबेस में सम्मिलित करते समय उस कॉलम को अनदेखा कर देगा और डिफ़ॉल्ट मान का उपयोग किया जाएगा।

इस लिंक को देखें: http://mariemjabloun.blogspot.com/2014/03/resolve-set-database-default-value-in.html


2
तो फिर दिए गए मान को कैसे जोड़ेंगे @runtime ??
आशीष रतन

हाँ वह सच है। nullable=falseएक साथ विफल हो जाएगा SqlException: Caused by: java.sql.SQLException: Column 'opening_times_created' cannot be null। यहाँ मैं "बनाया" टाइमस्टैम्प के साथ सेट करना भूल गया openingTime.setOpeningCreated(new Date())। यह संगति होने का एक अच्छा तरीका है, लेकिन यह वही है जो प्रश्नकर्ता नहीं पूछ रहा था।
रोलैंड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.