سؤال

أنا أعمل حاليًا مع envers hibernate.

كيفية حذف الإدخالات في جدول التدقيق المتعلق بالكيان الذي أريد حذفه؟ كياني ليس له علاقة مع الكيانات الأخرى.

اكتشفت أنه يجب علي القيام بذلك onPostDelete طريقة مستمعي المخصص:

import org.hibernate.envers.event.AuditEventListener;
import org.hibernate.event.PostCollectionRecreateEvent;
import org.hibernate.event.PostDeleteEvent;
import org.hibernate.event.PostInsertEvent;
import org.hibernate.event.PostUpdateEvent;
import org.hibernate.event.PreCollectionRemoveEvent;
import org.hibernate.event.PreCollectionUpdateEvent;

public class MyListener extends AuditEventListener {

  ...
  @Override
  public void onPostDelete(PostDeleteEvent arg0) {
    // TODO Auto-generated method stub
    super.onPostDelete(arg0);
  }
  ...

}

لقد قرأت الوثائق ، المنتديات ، أشياء كثيرة ولكن لا يمكنني معرفة ذلك. ربما لا يكون ذلك ممكنًا ، لا أعرف.

هل قام شخص ما بهذا من قبل؟

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

المحلول

حسنًا ، لقد انتهيت مع هذا بنسبة 50 ٪ لأولئك الذين يريدون معرفة ذلك.

بفضل منشئ السبات ، آدم وارسكي ، أقتبس:

"ID" هي كلمة رئيسية للإسبات لمعرف الكيان ، مهما كانت الأسماء ؛ في حالة كيانات التدقيق ، يكون المعرف مركبًا ويسمى "OriginalId". محاولة:

"delete from full.package.name.User_AUD u where u.originalId.id = :userid" 

لكن الآن ، أود أيضًا حذف الإدخالات المتعلقة بجدول التدقيق في جدول Revinfo الخاص بي.

إذا كان لدى شخص ما أدنى فكرة ، فأخبرني بذلك.

نصائح أخرى

هذا يعمل بشكل كامل بالنسبة لي ، و لا مطلوب استعلام أصلي

AuditQuery aq = auditReader.createQuery()
                   .forRevisionsOfEntity( ErpEmploye.class, true, false);       
 aq.add( AuditEntity.id().eq( employe.getCodeId() ) );
 aq.add( AuditEntity.relatedId("period").eq( erpPeriod.getCodeId() ) );
 List result =  aq.getResultList();//parameters must be added, this call is required
 if (result.size()>0){
    Query query = (Query) PrivateAccessor.invokePrivateMethod( aq, "buildQuery", new Object[0]);
    String queryString = (String) PrivateAccessor.getPrivateField( query, "queryString", true );
    PrivateAccessor.setPrivateField( query, "queryString", queryString.replace("select e__ from", "delete from"), true );
    getDAO().executeQuery(query);//transaction required             
}

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

فيما يلي بعض المقتطفات المكتوبة في كوتلين:

fun getAuditTableName(em: EntityManager, aClass: Class<*>): String {
    return getAuditTableName(em, aClass.name) + "_AUD"
}

fun getEntityTableName(em: EntityManager, aClass: Class<*>): String {
    val session = em.unwrap(Session::class.java) as Session
    val sessionFactory = session.sessionFactory
    val hibernateMetadata = sessionFactory.getClassMetadata(className)
    val persister = hibernateMetadata as AbstractEntityPersister
    return persister.tableName
}

الآن بعد أن أصبح لدينا اسم الجدول ، يمكننا إزالة الصفوف في الجداول. (ضع هذا في كتلة معاملات JPA الخاصة بك ، واستبدل المحتوى حسب الحاجة ، وضبط SQL لمزودك). لذلك بالنظر إلى myentityclass و myrevisionID ، يمكننا أن نفعل شيئًا كهذا:

    val em:EntityManager = getEntityManager()
    val auditTableName = getAuditTableName(MyEntityClass::class.java)

    em.createNativeQuery("delete from `$auditTableName` where REV=${myRevisionId}").executeUpdate()
    em.createNativeQuery("delete from REVINFO where REV=${myRevisionId}").executeUpdate()

إذا كنت ترغب في حذف معلمة بخلاف RevisionID ، فما عليك سوى الاستعلام عن المراجعات في جدول entity_aud ، ثم حذف الصفوف التي تم العثور عليها بالطريقة المذكورة.

ضع في اعتبارك أن المراجعة قد تترافق مع أكثر من كيان واحد ، وسيتم إزالة جميع الإدخالات في الطريقة السابقة. لحذف المراجعة لكيان واحد ، ستحتاج إلى معرف كيان وحقل الكيس الخاص بالكيان.

فيما يلي رمز للحصول على اسم الحقل ديناميكيًا:

fun getEntityKeyNames(em: EntityManager, entityClass: Class<*>): List<String> {
    val session = em.unwrap(Session::class.java) as Session
    val sessionFactory = session.sessionFactory
    val hibernateMetadata = sessionFactory.getClassMetadata(entityClass.name)
    val persister = hibernateMetadata as AbstractEntityPersister
    return persister.keyColumnNames.toList()
}

عادةً ما يتم إضافة إدخالات التدقيق فقط ، ولا يتم حذفها ، حتى عندما يتم حذف الكيان ذي الصلة حتى لا أفعل فكر في أن واجهة برمجة تطبيقات Envers توفر الدعم لذلك.

الآن ، إذا كنت ترغب حقًا في إزالة الإدخالات للكيانات المحذوفة (هذا يهزم الغرض من التدقيق) ، فيمكنك تأخير هذا الأمر قليلاً وبدلاً من إزالة الإدخالات في وقت الحذف ، قم بتشغيل استعلام يومي يوميًا ، على سبيل المثال كل ليلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top