سؤال

لدي مشكلة بسيطة @OneToMany رسم الخرائط بين الوالد والكيان الطفل. كل شيء يعمل بشكل جيد، فقط عدم حذف سجلات الأطفال عند إزالتها من المجموعة.

الاباء:

@Entity
public class Parent {
    @Id
    @Column(name = "ID")
    private Long id;

    @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "parent")
    private Set<Child> childs = new HashSet<Child>();

 ...
}

الطفل:

@Entity
public class Child {
    @Id
    @Column(name = "ID")
    private Long id;

    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name="PARENTID", nullable = false)
    private Parent parent;

  ...
}

إذا قمت الآن بحذف وطفل من مجموعة الأطفال، فلن يتم حذفها من قاعدة البيانات. حاولت إلغاء child.parent مرجع، ولكن هذا لم يعمل أيضا.

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

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

المحلول

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

في جزء منه، لأن JPA لا يعرف في الواقع ما إذا كان يجب إزالته شيئا من المجموعة. في شروط نمذجة الكائن، هذا هو الفرق بين تعبير و "التجميع *.

في تعبير, ، كيان الطفل ليس لديه وجود دون الوالد. مثال كلاسيكي بين المنزل والغرفة. حذف المنزل وتذهب الغرف أيضا.

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

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

أنا على علم:

نصائح أخرى

بالإضافة إلى إجابة كليتوس، JPA 2.0., ، النهائي منذ ديسمبر 2010، يقدم orphanRemoval سمة على @OneToMany التوضيحية. لمزيد من التفاصيل نرى هذا مدونة المدونة.

لاحظ أنه نظرا لأن المواصفات جديدة نسبيا، فلن يكون لكل مزود JPA 1 تطبيق JPA 2 نهائي. على سبيل المثال، الإصدار 3.5.0-Beta-2 لا يدعم بعد هذه السمة.

يمكنك تجربة هذا:

@OneToOne(orphanRemoval=true) or @OneToMany(orphanRemoval=true).

كما هو موضح، ليس من الممكن القيام بما أريد مع JPA، لذلك استخدمت التعليق التوضيحي لعدم العينات.

@OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}, mappedBy = "parent")
@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE,
            org.hibernate.annotations.CascadeType.DELETE,
            org.hibernate.annotations.CascadeType.MERGE,
            org.hibernate.annotations.CascadeType.PERSIST,
            org.hibernate.annotations.CascadeType.DELETE_ORPHAN})
private Set<Child> childs = new HashSet<Child>();

لم أستطع استخدام بسيط "الكل" لأن هذا كان من شأنه حذف الوالد كذلك.

هنا تتالي، في سياق إزالة، يعني إزالة الأطفال إذا قمت بإزالة الوالد. ليس الجمعية. إذا كنت تستخدم السبات كموفر JPA الخاص بك، فيمكنك القيام بذلك باستخدام سباتات خاصة Cascade..

يمكنك تجربة هذا:

@OneToOne(cascade = CascadeType.REFRESH) 

أو

@OneToMany(cascade = CascadeType.REFRESH)
@Entity 
class Employee {
     @OneToOne(orphanRemoval=true)
     private Address address;
}

يرى هنا.

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