السباتOneToMany مع mappedBy (الوالدين والطفل) العلاقة ومخبأ مشكلة

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

سؤال

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

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

@Entity
public class Parent {
    // ...

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    private Set<Child> children = new HashSet<Child>();

    // ...
}

@Entity
public class Child {
    // ...

    @ManyToOne(fetch = FetchType.LAZY)
    private Parent parent;

    // ...
}

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

 Parent parent = new Parent();
 em.persist(parent);

 // ...

 Child child = new Child();
 child.setParent(parent);
 em.persist(child);

 parent.getChildren().size(); // returns 0

ولقد حاولت استخدامPreUpdate لإضافة تلقائيا الطفل إلى الأم عند استمر الطفل، ولكن في حالة عندما يكون لدينا 2 مديري الكيانات في 2 المواضيع المختلفة (مثل في جبوس)، والقضية لا يزال موجودا، حتى ندعو em.refresh(parent)

ولذا فإن السؤال هو - هل هناك وسيلة للقضاء بسلاسة المشكلة وضمان parent.getChildren() دائما العودة قائمة الأطفال يصل إلى التاريخ

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

المحلول

ومعظم لORM سوف تتصرف بهذه الطريقة.

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

وحتى إذا كنت تريد الكائن المراد إضافتها إلى المجموعة ثم القيام بذلك في رمز "setParent".

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

وإضافة أسلوب إلى الأصل يسمى addChild

 public void addChild(Child child) {
    child.setParent0(this);
    getChildren().add(individualNeed);
 }

وثم جعل setParent في الطفل:

public void setParent(Parent parent) {
   parent.addChild(child);
}

وsetParent0 في الطفل هو stter الملكية لالأصل على الأطفال.

public void setParent0(Parent parent) {
   this.parent = parent;
}

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

وأكثر شيء واحد، يجب أن يكون كود التحقق اغيا وقطع الدفاعية الأخرى في رمز أعلاه، تركت بها لوضوح.

نصائح أخرى

ومتأكد من مشكلتك هنا هي إعدادات تتالي الخاص بك.

@Entity
public class Parent {
   // ...

   @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, 
      cascade = {CascadeType.REMOVE, CascadeType.PERSIST})
   @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
   private Set<Child> children = new HashSet<Child>();

   // ...
}

@Entity
public class Child {
    // ...

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
    @Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
    private Parent parent;

    // ...
}
<ع> استخدام هذه الإعدادات شلال سوف تستمر تتالي والتحديثات على الكائنات التابعة.

وعلى سبيل المثال.

Parent parent = new Parent();
em.persist(parent);

// ...

Child child = new Child();
child.setParent(parent);
em.persist(child); //will cascade update to parent

parent.getChildren().size(); // returns 1

أو

Parent parent = new Parent();
Child child = new Child();
parent.setChild(parent);
em.persist(parent); //will cascade update to child

child.getParent(); // returns the parent

ومزيد من المعلومات عن هذا ويمكن الاطلاع على الموقع السبات الشروح

وفيما يتعلق مشكلتك مع التخزين المؤقت، وهذا هو مشكلة شائعة جدا عندما يكون لديك نظام رصد السفن متعددة تعمل على نفس قاعدة البيانات مع مخابئ منفصلة. انه دعا "الانجراف مخبأ".

ومعظم تطبيقات مخبأ صديقة للالسبات (ehcache، OSCache وSwarmCache) لديها مخبأ للتوزيع المضمنة التي يمكن استخدامها لمزامنة مخابئ. ذاكرة التخزين المؤقت الموزعة، عموما، يرسل رسائل الإرسال المتعدد تحديث الدولة من ذاكرة التخزين المؤقت. القيام الثاني الإخلاء مخبأ مستوى من SessionFactory.evict (الفئة، معرف)، على سبيل المثال، سوف يسبب رسالة إبطال ليتم إرسالها إلى مخابئ أخرى في الكتلة التي سوف يبطل أي نسخ أخرى من هذا الكائن في مخابئ أخرى.

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

وأنا شخصيا وجدت تكوين مخبأ موزعة إيه ذاكرة التخزين المؤقت واضحة جدا.

يناقش

وEH مخبأ المشكلة في المزيد من التفاصيل قليلا هنا: http://ehcache.org/documentation/ distributed_caching.html

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