জেপিএ: একমুখী বহু-এক-এক এবং ক্যাসকেডিং মোছা


98

বলুন যে আমার নীতির @ManyToOne মতো একমুখী সম্পর্ক আছে :

@Entity
public class Parent implements Serializable {

    @Id
    @GeneratedValue
    private long id;
}

@Entity
public class Child implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @ManyToOne
    @JoinColumn
    private Parent parent;  
}

যদি আমার পিতামাত P এবং বাচ্চাদের সি 1 ... সি এন পি তে উল্লেখ করে থাকে, পি সরানো হলে (যেমন ) বাচ্চাদের স্বয়ংক্রিয়ভাবে C 1 ... C এন সরিয়ে দেওয়ার জন্য কি জেপিএতে একটি পরিষ্কার এবং সুন্দর উপায় আছে entityManager.remove(P)?

আমি যা খুঁজছি তা ON DELETE CASCADEএসকিউএল এর অনুরূপ একটি কার্যকারিতা ।


4
এমনকি 'সন্তানের' কাছে 'পিতামাতার' একটি রেফারেন্স থাকলেও (সেইভাবে রেফারেন্সিং দিকনির্দেশনামূলক) আপনার পক্ষে '@OneToMany' ম্যাপিং এবং 'ক্যাসকেড = সমস্ত' বৈশিষ্ট্যের সাথে 'সন্তানের' তালিকা যুক্ত করা সমস্যাযুক্ত কি? পিতামাতা'? আমি ধরে নিয়েছি যে জেপিএর সমাধান করা উচিত এমনকি শক্ত মাত্র 1 পক্ষের রেফারেন্স রয়েছে holds
কেভিডেনিস

4
@ কেভিডেনিস, এমন অনেকগুলি ক্ষেত্রে রয়েছে যেখানে আপনি একপাশে বহু পক্ষকে শক্তভাবে জুড়তে চান না। যেমন ACL- এর মতো সেটআপগুলিতে যেখানে সুরক্ষা অনুমতিগুলি স্বচ্ছ "অ্যাড-অন"
বাচি

উত্তর:


73

জেপিএ-র সম্পর্কগুলি সর্বদা একমুখী হয়, যদি না আপনি উভয় দিক দিয়ে সন্তানের সাথে পিতামাতার সাথে যুক্ত হন। সন্তানের কাছে পিতামাতার কাছ থেকে অপসারণ অপসারণের জন্য পিতামাতার কাছ থেকে সন্তানের সাথে সম্পর্কের প্রয়োজন হবে (কেবল বিপরীতে নয়)।

সুতরাং আপনার এটি করতে হবে:

  • হয়, @ManyToOneদিকনির্দেশক সম্পর্ককে দ্বি-দিকনির্দেশক @ManyToOne, বা দিকনির্দেশনাতে পরিবর্তন করুন @OneToMany। এরপরে আপনি EntityManager.removeঅপসারণ অপারেশনগুলিকে ক্যাসকেড করতে পারেন যাতে পিতামাতার এবং বাচ্চাদের সরিয়ে দেওয়া হয়। আপনি orphanRemovalসত্য হিসাবেও নির্দিষ্ট করতে পারেন , পিতামাতার সংগ্রহে থাকা শিশু সত্তাটি বাতিল হয়ে গেলে যে কোনও অনাথ শিশুকে মুছে ফেলতে, অর্থাত্ কোনও পিতামাতার সংগ্রহে উপস্থিত না থাকলে শিশুটিকে সরিয়ে ফেলুন।
  • বা, শিশু টেবিলে বিদেশী কী সীমাবদ্ধতা নির্দিষ্ট করুন ON DELETE CASCADE। দৃ EntityManager.clear()calling EntityManager.remove(parent)়তা প্রসঙ্গে রিফ্রেশ হওয়া দরকার বলে ডাকার পরে আপনাকে ডাকতে হবে - শিশু সত্তা ডাটাবেসে মুছে ফেলার পরে অধ্যবসায় প্রসঙ্গে উপস্থিত থাকার কথা নয়।

7
জেপিএ টীকা দিয়ে কি নো 2 করার উপায় আছে?
ব্যবহারকারী 2573153

4
হাইবারনেট এক্সএমএল ম্যাপিংয়ের সাহায্যে আমি কীভাবে 2 করব?
আরজি 20

94

আপনি যদি আপনার জেপিএ সরবরাহকারী হিসাবে হাইবারনেট ব্যবহার করছেন তবে আপনি টিকাটি @ অনডিলিট ব্যবহার করতে পারেন। এই টীকাটি ডিলেট ডিএসিটি কেসকেডে সম্পর্কের সাথে যুক্ত করে , যা বাচ্চাদের মুছে ফেলার জন্য ডেটাবেসে প্রতিনিধিত্ব করে।

উদাহরণ:

public class Parent {

        @Id
        private long id;

}


public class Child {

        @Id
        private long id;

        @ManyToOne
        @OnDelete(action = OnDeleteAction.CASCADE)
        private Parent parent;
}

এই সমাধানের মাধ্যমে বাচ্চাদের কাছ থেকে অভিভাবকের সাথে একমুখী সম্পর্ক হ'ল সমস্ত শিশুকে স্বয়ংক্রিয়ভাবে সরানোর জন্য যথেষ্ট। এই সমাধানটির কোনও শ্রোতার দরকার নেই ইত্যাদি Also এছাড়াও আইডি = 1 থেকে পিতামাতার থেকে মুছে ফেলার মতো একটি কোয়েরি বাচ্চাদের সরিয়ে ফেলবে।


4
আমি এটিকে এভাবে কাজ করতে পারি না, হাইবারনেটের কোনও নির্দিষ্ট সংস্করণ বা এর মতো আরও বিশদ উদাহরণ রয়েছে কি?
মার্ডারি

4
এটি আপনার পক্ষে কেন কাজ করছে না তা বলা শক্ত। এটি কাজ করার জন্য আপনাকে স্কিমাটি পুনরায় তৈরি করতে হতে পারে অথবা আপনাকে ম্যানুয়ালি ক্যাসকেড মুছতে হবে। @ অ্যানডিলিট টীকাটি কিছু সময়ের জন্য প্রায় মনে হচ্ছে যেমন আমি ধারণা করতে পারি না যে সংস্করণটি একটি সমস্যা।
থমাস হুনজিকার

12
উত্তর করার জন্য ধন্যবাদ. দ্রুত দ্রষ্টব্য: আপনি হাইবারনেটের মাধ্যমে ডিডিএল জেনারেশন সক্ষম করলেই ডাটাবেস ক্যাসকেড ট্রিগার তৈরি হবে। অন্যথায় আপনাকে এটিকে এইভাবে অন্য কোনও উপায় যুক্ত করতে হবে (উদাহরণস্বরূপ তরল পদার্থবিজ্ঞান) ডিবি-র বিরুদ্ধে সরাসরি 'অভিভাবক থেকে আইডি = 1 মুছে ফেলুন' যেমন ক্যাসকেড অপসারণ সম্পাদনের অনুমতি দেয় allow
mjj1409

4
এটি কাজ করছে না যখন সমিতি @OneToOneকোনও ধারণা এটির সাথে কীভাবে সমাধান করবেন @OneToOne?
stakowerflol

4
@ থমাস হানজিকার এই অনাথ সরানোর জন্য কাজ করবে না?
অক্সিট

14

একটি দ্বি-দিকনির্দেশক সম্পর্ক তৈরি করুন:

@Entity
public class Parent implements Serializable {

    @Id
    @GeneratedValue
    private long id;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE)
    private Set<Child> children;
}

9
খারাপ উত্তর, দ্বিপাক্ষিক সম্পর্ক
জেপিএতে

4
দ্বি-নির্দেশমূলক সম্পর্ক ধীর হওয়ার প্রমাণ রয়েছে কি?
শালামা

@ এনারসিসিও দ্বি-দিকীয় সম্পর্ক যদি একের সাথে হয়? এছাড়াও, দয়া করে একটি নিবন্ধ দেখান যা জানিয়েছে যে দ্বি-দিকনির্দেশক সম্পর্কগুলি ধীর? কি ধীর? পুনরুদ্ধার করা হচ্ছে? মোছা? আপডেটিং?
saran3h

@ সরান 3 ঘন্টা প্রতিটি ক্রিয়াকলাপ (যোগ করুন, সরান) সমস্ত শিশুকে লোড করবে, যাতে এটি প্রচুর ডেটা লোড যা অকেজো হতে পারে (যেমন একটি মান যুক্ত করার ফলে ডেটাবেস থেকে সমস্ত শিশুকে বোঝানো হয় না যা এই ম্যাপিংয়ের কাজটি ঠিক তাই করে)।
এনারসিসিও

@ এন্টার্কিও আমি মনে করি সবাই যোগ দিয়ে অলস লোডিং ব্যবহার করে। সুতরাং এটি এখনও একটি পারফরম্যান্স সমস্যা?
saran3h

2

আমি একমুখী @ ম্যানিটোঅনে দেখেছি, মোছা প্রত্যাশার মতো কাজ করবে না। যখন পিতামাতাকে মুছে ফেলা হয়, তখন আদর্শভাবে শিশুটিকেও মুছে ফেলা উচিত তবে কেবল পিতামাতাকে মুছে ফেলা হয় এবং শিশুটিকে মুছে ফেলা হয় না এবং এতিম হিসাবে রেখে দেওয়া হয়

ব্যবহৃত প্রযুক্তি হ'ল স্প্রিং বুট / স্প্রিং ডেটা জেপিএ / হাইবারনেট

স্প্রিন্ট বুট: 2.1.2. নিখরচায়

স্প্রিং ডেটা জেপিএ / হাইবারনেট সারি .eg মুছতে ব্যবহৃত হয়

parentRepository.delete(parent)

প্যারেন্টিরিপোসিটরিটি নীচের মত দেখায় যেমন স্ট্যান্ডার্ড সিআরইউডি সংগ্রহস্থল প্রসারিত করে ParentRepository extends CrudRepository<T, ID>

নিম্নলিখিত আমার সত্তা শ্রেণি হয়

@Entity(name = “child”)
public class Child  {

    @Id
    @GeneratedValue
    private long id;

    @ManyToOne( fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = “parent_id", nullable = false)
    @OnDelete(action = OnDeleteAction.CASCADE)
    private Parent parent;
}

@Entity(name = “parent”)
public class Parent {

    @Id
    @GeneratedValue
    private long id;

    @Column(nullable = false, length = 50)
    private String firstName;


}

মুছুন কেন কাজ করছে না তার সমাধান খুঁজে পেয়েছি। স্পষ্টত হাইবারনেটটি মাইএসকিএল ইঞ্জিন -আইএনএনওডিবি ব্যবহার করছিল না, বিদেশী কী সীমাবদ্ধতা তৈরি করতে আপনার মাইএসকিএল-এর জন্য INNODB ইঞ্জিন প্রয়োজন। অ্যাপ্লিকেশন.প্রোপার্টিগুলিতে নিম্নলিখিত বৈশিষ্ট্যগুলি ব্যবহার করে, মাইএসকিএল ইঞ্জিন আইএনএনওডিবি ব্যবহারের জন্য বসন্ত বুট / হাইবারনেট তৈরি করে। সুতরাং বিদেশী কী বাধা কাজ করে এবং তাই ক্যাসকেড মোছা করে
রঞ্জেশ

মিস করা বৈশিষ্ট্যগুলি আগের মন্তব্যে ব্যবহার করুন। নীচে বসন্তের বৈশিষ্ট্যগুলি ব্যবহার করা হয়েছেspring.jpa.hibernate.use-new-id-generator-mappings=true spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
রণেশেশ

এফওয়াইআই, কোডটিতে আপনার ভুল আছে "। দেখুনname= "parent"
আলেকজান্দার

0

শুধুমাত্র এক পক্ষ মুছতে এই উপায়টি ব্যবহার করুন

    @ManyToOne(cascade=CascadeType.PERSIST, fetch = FetchType.LAZY)
//  @JoinColumn(name = "qid")
    @JoinColumn(name = "qid", referencedColumnName = "qid", foreignKey = @ForeignKey(name = "qid"), nullable = false)
    // @JsonIgnore
    @JsonBackReference
    private QueueGroup queueGroup;

-1

পছন্দ করুন

প্রদত্ত টিকা আমার জন্য কাজ করেছে। চেষ্টা করতে পারেন

উদাহরণ স্বরূপ :-

     public class Parent{
            @Id
            @GeneratedValue(strategy=GenerationType.AUTO)
            @Column(name="cct_id")
            private Integer cct_id;
            @OneToMany(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER,mappedBy="clinicalCareTeam", orphanRemoval=true)
            @Cascade(org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
            private List<Child> childs;
        }
            public class Child{
            @ManyToOne(fetch=FetchType.EAGER)
            @JoinColumn(name="cct_id")
            private Parent parent;
    }

-1

আপনার কোডের পরিবর্তে আপনার দ্বি-দিকনির্দেশক সমিতি ব্যবহার করার দরকার নেই, আপনাকে কেবল ক্যাসকাটাইপ যুক্ত করতে হবে Many ম্যান্টিটো ওয়ান টীকা হিসাবে সম্পত্তি হিসাবে সরান, তারপরে @ অনডিলিট (ক্রিয়া = অনডিলিটএকশন.ক্যাসক্যাডে) ব্যবহার করুন, এটি আমার পক্ষে ভাল কাজ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.