هل تريد تعيين عمود الطابع الزمني JPA ليتم إنشاؤه بواسطة قاعدة البيانات؟

StackOverflow https://stackoverflow.com/questions/811845

سؤال

في قاعدة بيانات SQL Server 2000 الخاصة بي، لدي عمود طابع زمني (في الوظيفة وليس في نوع البيانات) من النوع DATETIME اسم الشيئ lastTouched ضبط ل getdate() كقيمة/ربط افتراضية.

أنا أستخدم فئات كيانات JPA التي تم إنشاؤها في Netbeans 6.5، ولدي هذا في الكود الخاص بي

@Basic(optional = false)
@Column(name = "LastTouched")
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;

ولكن عندما أحاول وضع الكائن في قاعدة البيانات، أحصل عليه،

javax.persistence.PersistenceException: org.hibernate.PropertyValueException: not-null property references a null or transient value: com.generic.Stuff.lastTouched

لقد حاولت إعداد إعداد @Basic ل (optional = true), ، ولكن هذا يطرح استثناءً يفيد بأن قاعدة البيانات لا تسمح بذلك null القيم ل TIMESTAMP العمود، وهو ليس حسب التصميم.

ERROR JDBCExceptionReporter - Cannot insert the value NULL into column 'LastTouched', table 'DatabaseName.dbo.Stuff'; column does not allow nulls. INSERT fails.

لقد قمت سابقًا بتشغيل هذا في وضع السبات الخالص، ولكن لدي شعور بالتحول إلى JPA وليس لدي أي فكرة عن كيفية إخباره أنه من المفترض أن يتم إنشاء هذا العمود من جانب قاعدة البيانات.لاحظ أنني ما زلت أستخدم Hibernate كطبقة ثبات JPA الخاصة بي.

هل كانت مفيدة؟

المحلول

وأنا إصلاح المشكلة عن طريق تغيير الرمز إلى

@Basic(optional = false)
@Column(name = "LastTouched", insertable = false, updatable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date lastTouched;

وهكذا يتم تجاهل العمود الطابع الزمني عند إنشاء إدراج SQL. لست متأكدا إذا كان هذا هو أفضل وسيلة للذهاب حول هذا الموضوع. ردود الفعل هو موضع ترحيب.

نصائح أخرى

وأنا أدرك هذا متأخرا بعض الشيء، ولكن لقد كان النجاح مع التأشير عمود الطابع الزمني مع

@Column(name="timestamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP")

وهذا يجب أن تعمل أيضا مع CURRENT_DATE وCURRENT_TIME. أنا باستخدام JPA / السبات مع أوراكل، لذلك YMMV.

@Column(nullable = false, updatable = false)
@CreationTimestamp
private Date created_at;

وهذا العمل بالنسبة لي. مزيد من المعلومات

ولدي هذا JPA2.0 تعمل بشكل جيد باستخدام و MySQL 5.5.10، في الحالات التي ما يهمني هو آخر مرة تم فيها تعديل الصف. سوف الخلية إنشاء الطابع الزمني على الإدراج الأول، ويسمى كل UPDATE الوقت على التوالي. (ملاحظة: هذا لن يكون مشكلة إذا كنت تهتم أم لا UPDATE جعلت في الواقع تغيير).

وعمود "الطابع الزمني" في هذا المثال هو مثل column.x` "آخر تطرق"

ويستخدم رمز أدناه عمود منفصل "نسخة" لتأمين متفائل.

private long version;
private Date timeStamp

@Version
public long getVersion() {
    return version;
}

public void setVersion(long version) {
    this.version = version;
}

// columnDefinition could simply be = "TIMESTAMP", as the other settings are the MySQL default
@Column(name="timeStamp", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
@Temporal(TemporalType.TIMESTAMP)
public Date getTimeStamp() {
    return timeStamp;
}

public void setTimeStamp(Date timeStamp) {
    this.timeStamp = timeStamp;
}

و(ملاحظة:version لا يعمل على عمود الخلية "DATETIME"، حيث نوع السمة "التاريخ" في فئة الكيان وكان هذا لأن التسجيل كان تولد قيمة وصولا الى ميلي ثانية واحدة، ولكن كان لا ماي تخزين ميلي ثانية واحدة، وذلك عندما فعلت مقارنة بين ما كان في قاعدة البيانات، و "تعلق" كيان، فإنه يعتقد انهم أرقام الإصدارات المختلفة)

من دليل الخلية بشأن الطابع الزمني :

With neither DEFAULT nor ON UPDATE clauses, it is the same as DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.

لا أعتقد أن كل قاعدة بيانات لها طوابع زمنية للتحديث التلقائي (على سبيل المثال.بوستجرس).لذلك قررت تحديث هذا الحقل يدويًا في كل مكان في الكود الخاص بي.سيعمل هذا مع كل قاعدة بيانات:

thingy.setLastTouched(new Date());
HibernateUtil.save(thingy);

هناك أسباب لاستخدام المحفزات، ولكن بالنسبة لمعظم المشاريع، هذه ليست واحدة منها.تحفرك المشغلات بشكل أعمق في تنفيذ قاعدة بيانات محددة.

ماي إس كيو إل 5.6يبدو أن .28 (Ubuntu 15.10، OpenJDK 64-Bit 1.8.0_66) متسامح للغاية، ولا يتطلب أي شيء يتجاوز ذلك

@Column(name="LastTouched")

ماي إس كيو إل 5.7.9 (CentOS 6، OpenJDK 64-Bit 1.8.0_72) يعمل فقط مع

@Column(name="LastTouched", insertable=false, updatable=false)

لا:

FAILED: removing @Temporal
FAILED: @Column(name="LastTouched", nullable=true)
FAILED: @Column(name="LastTouched", columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")

معلومات النظام الأخرى الخاصة بي (متطابقة في كلا البيئتين)

  • السبات-مدير الكيان 5.0.2
  • مدقق السبات 5.2.2
  • MySQL-موصل-جافا 5.1.38
@Column(name = "LastTouched", insertable = false, updatable = false, columnDefinition = "TIMESTAMP default getdate()")
@Temporal(TemporalType.TIMESTAMP)
private Date LastTouched;`enter code here`
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top