العثور على مراجع مشتركة إلى مجموعة ORG.Ibernate.hibernateException

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

سؤال

حصلت على رسالة الخطأ هذه:

خطأ: وجدت مراجع مشتركة إلى مجموعة: شخص.

عندما حاولت التنفيذ addToRelatedPersons(anotherPerson):

person.addToRelatedPersons(anotherPerson);
anotherPerson.addToRelatedPersons(person);

anotherPerson.save();
person.save();

مجالي:

Person {

 static hasMany = [relatedPersons:Person];

}

أي فكرة لماذا يحدث هذا ؟

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

المحلول

يظهر السبات هذا الخطأ عند محاولة الاستمرار في مشاركة أكثر من مثيل كيان واحد نفس إشارة جمع (أي هوية المجموعة على النقيض من تكوين المساواة).

لاحظ أنه يعني نفسه مجموعة, وليس عنصر جمع - بمعنى آخر relatedPersons على كليهما person و anotherPerson يجب أن يكون هو نفسه. ربما كنت إعادة تعيين هذه المجموعة بعد تحميل الكيانات؟ أو قمت بتهيئة المراجع مع نفس مثيل المجموعة؟

نصائح أخرى

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

بالنظر إلى أنني أمضيت بعض الوقت في التحقيق في هذه المسألة، أود أن أوصي قائمة المراجعة التالية:

  • ابحث عن سيناريوهات مثل entity1.setCollection(entity2.getCollection()) و getCollection إرجاع المرجع الداخلي إلى المجموعة (إذا كان GetCollection () إرجاع مثيل جديد للمجموعة، فأنت لا داعي للقلق).

  • انظر إذا clone() تم تنفيذها بشكل صحيح.

  • ابحث عن BeanUtils.copyProperties(entity1, entity2).

تفسير في الممارسة. إذا حاولت حفظ الكائن الخاص بك، على سبيل المثال:

Set<Folder> folders = message.getFolders();
   folders.remove(inputFolder);
   folders.add(trashFolder);
   message.setFiles(folders);
MESSAGESDAO.getMessageDAO().save(message);

لا تحتاج إلى تعيين كائن محدث إلى كائن الأصل:

message.setFiles(folders);

بسيطة حفظ كائن الأصل الخاص بك مثل:

Set<Folder> folders = message.getFolders();
   folders.remove(inputFolder);
   folders.add(trashFolder);
   // Not set updated object here
MESSAGESDAO.getMessageDAO().save(message);

القراءة عبر الإنترنت سبب هذا الخطأ يمكن أن يكون أيضا علة السبات, ، كما الحل البديل يبدو أنه يعمل، هو وضع:

session.clear()

يجب عليك وضع الواضح بعد الحصول على البيانات وقبل الالتزام والإغلاق، انظر المثال:

//getting data
SrReq sr = (SrReq) crit.uniqueResult();
SrSalesDetailDTO dt=SrSalesDetailMapper.INSTANCE.map(sr);
//CLEAR            
session.clear();
//close session
session.getTransaction().commit();
session.close();
return dt;

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

مشكلتي تساوي 100٪ من هذا: http://www.progtown.com/topic128073- dishernate-many-to-many-on-two-tables.html.

في حالتي، كنت نسخ ولصق رمز من فئاتي الأخرى، لذلك لم ألاحظ أن رمز Getter كان سيئا مكتوبا:

@OneToMany(fetch = FetchType.LAZY, mappedBy = "credito")
public Set getConceptoses() {
    return this.letrases;
}

public void setConceptoses(Set conceptoses) {
    this.conceptoses = conceptoses;
}

جميع المراجع المفاهيم ولكن إذا نظرت إلى Get يقول lerades.

أنا أيضا حصلت على نفس المشكلة، شخص يستخدم BeanUtils.copyProperties(source, target). وبعد هنا كل من المصدر والهدف، تستخدم نفس المجموعة كأسنان.

لذلك أنا فقط استخدمت النسخة العميقة على النحو التالي ..

كيفية استنساخ جمع في جافا - نسخة عميقة من القوائم وحاشت

واجهت استثناء مماثل في طلبي. بعد النظر إلى StackTrace، كان من الواضح أن الاستثناء قد ألقيته داخل FlushEntityEventListener صف دراسي.

في السبات 4.3.7 MSLocalSessionFactory الفول لم يعد يدعم eventListeners خاصية. وبالتالي، يتعين على المرء أن يجلب سجل الخدمة بشكل صريح من فاصوليات جلسة السبات الفردية ثم قم بتعيين مستمعي الأحداث المخصصين المطلوبين.

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

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

لذلك، تأكد من إزالة المستمعين المخصصين عند تسجيل المستمعين المخصصين من التسجيل.

النظر في كيان:

public class Foo{
private<user> user;
/* with getters and setters */
}

والنظر في فئة منطق الأعمال:

class Foo1{
List<User> user = new ArrayList<>();
user = foo.getUser();
}

هنا المستخدم و foo.getUser() مشاركة نفس المرجع. ولكن توفير المراجعين يخلق الصراع.

يجب أن يكون الاستخدام الصحيح:

class Foo1 {
List<User> user = new ArrayList<>();
user.addAll(foo.getUser);
}

وهذا يتجنب الصراع.

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