কীভাবে জেপিএ অরফান সরানো = অন ডিফল্ট ক্যাসকেড ডিএমএল ধারা থেকে সত্য


184

আমি জেপিএ ২.০ orphanRemovalবৈশিষ্ট্য সম্পর্কে কিছুটা বিভ্রান্ত ।

আমি মনে করি যে আমি যখন জেপিএ সরবরাহকারীর ডিবি প্রজন্মের সরঞ্জামগুলি ON DELETE CASCADEনির্দিষ্ট সম্পর্কের জন্য অন্তর্নিহিত ডাটাবেস ডিডিএল তৈরি করতে ব্যবহার করি তখন এটির প্রয়োজন দেখাতে পারি ।

তবে, ডিবি যদি বিদ্যমান থাকে এবং ইতিমধ্যে এটির ON DELETE CASCADEসম্পর্ক রয়েছে তবে এটি কি মুছে ফেলা যথাযথভাবে ক্যাসকেড করার পক্ষে যথেষ্ট নয়? এর সাথে কী করে orphanRemoval?

চিয়ার্স

উত্তর:


291

orphanRemovalএর সাথে কিছু করার নেই ON DELETE CASCADE

orphanRemovalএকটি সম্পূর্ণ ORM- নির্দিষ্ট জিনিস । এটি "সন্তানের" সত্তাটি মুছে ফেলা হবে যখন এটি "পিতামাতার" সত্তা থেকে আর রেফারেন্স করা হয় না, যেমন আপনি যখন পিতামাতার সত্তার সাথে সম্পর্কিত সংগ্রহ থেকে শিশু সত্তাটি সরিয়ে ফেলেন।

ON DELETE CASCADEএটি একটি ডাটাবেস-নির্দিষ্ট জিনিস , এটি "সন্তানের" সারিটি মুছে ফেলা হয় যখন "প্যারেন্ট" সারিটি মুছে ফেলা হয়।


3
এর অর্থ কি এই যে তারা নিরাপদ প্রভাব ফেলেছে, তবে এটি ঘটানোর জন্য একটি আলাদা সিস্টেম দায়বদ্ধ?
বেনামে

101
আনন, এটির একই প্রভাব নেই। অনুলিপি করা ক্যাসকেড ডিবিকে বলছে যখন পিতা-মাতা মুছে ফেলা হয় তখন সমস্ত শিশু রেকর্ড মুছতে। এটি যদি আমি ইনভয়েসটিকে মুছুন, তবে সেই ইনভয়েসের সমস্ত আইটিইএমএস মুছুন। অরফ্যানমোভাল ওআরএমকে বলে যে আমি যদি কোনও চালানের অবজেক্টের (স্মৃতি ক্রিয়াকলাপের সাথে সম্পর্কিত) আইটেমগুলির সংগ্রহ থেকে কোনও আইটেম অবজেক্টটি সরিয়ে ফেলি এবং তারপরে "সংরক্ষণ" করি, তবে সরানো আইটেমটি অন্তর্নিহিত ডিবি থেকে মুছে ফেলা উচিত।
garyKeorkunian

2
আপনি যদি একতরফা-নির্দেশমূলক সম্পর্ক ব্যবহার করেন তবে অনাথকে অপসারণ না করা সত্ত্বেও এতিমটি স্বয়ংক্রিয়ভাবে সরানো হবে = সত্য
টিম

98

এখানে একটি উদাহরণ গৃহীত :

যখন কোনও Employeeসত্তা অবজেক্ট সরানো হয়, অপসারণ অপারেশনটি রেফারেন্সকৃত Addressসত্তা অবজেক্টে ক্যাসকেড করা হয় । এই ক্ষেত্রে, orphanRemoval=trueএবং cascade=CascadeType.REMOVEঅভিন্ন, এবং যদি orphanRemoval=trueনির্দিষ্ট করা হয়, CascadeType.REMOVEনিরর্থক।

দুটি সেটিংসের মধ্যে পার্থক্য একটি সম্পর্ক বিচ্ছিন্ন করার প্রতিক্রিয়াতে। উদাহরণস্বরূপ, যেমন ঠিকানা ক্ষেত্রটি সেট করার সময় nullবা অন্য কোনও Addressবস্তুতে।

  • যদি orphanRemoval=trueহয় নিদিষ্ট বিচ্ছিন্ন Addressউদাহরণস্বরূপ স্বয়ংক্রিয়ভাবে মুছে ফেলা হবে। এটি নির্ভরশীল অবজেক্টগুলি পরিষ্কার করার জন্য দরকারী (উদাহরণস্বরূপ Address) যা কোনও মালিকের অবজেক্টের (উদাহরণস্বরূপ Employee) কোনও রেফারেন্স ছাড়াই থাকা উচিত নয় ।

  • শুধুমাত্র cascade=CascadeType.REMOVEযদি নির্দিষ্ট করা থাকে তবে কোনও সম্পর্ক বিচ্ছিন্ন করা কোনও অপসারণ অপারেশন নয় বলে কোনও স্বয়ংক্রিয় পদক্ষেপ নেওয়া হয় না।

এতিম অপসারণের ফলস্বরূপ ঝুঁকির রেফারেন্স এড়ানোর জন্য, এই বৈশিষ্ট্যটি কেবলমাত্র এমন ক্ষেত্রগুলির জন্য সক্ষম করা উচিত যা ব্যক্তিগত অ ভাগ করা নির্ভরশীল বস্তু রাখে।

আমি আশা করি এটি আরও স্পষ্ট করে তোলে।


আপনার উত্তরটি পড়ার পরে, আমি বুঝতে পারি যে তাদের উভয়ের মধ্যেই ঠিক পার্থক্য রয়েছে এবং আমার সমস্যাটি সমাধান হয়ে গেছে। আমি পিতামাতার সত্তায় সংজ্ঞায়িত সংগ্রহ থেকে সংযোগ বিচ্ছিন্ন (অপসারণ) হলে ডাটাবেস থেকে শিশু সত্তাগুলি মুছতে আটকে গিয়েছি। একই জন্য আমি প্রশ্নটি জিজ্ঞাসা করেছি ' স্ট্যাকওভারফ্লো . com/ জিজ্ঞাসা / 15526440/… '। উভয় প্রশ্নের লিঙ্ক করতে আমার মন্তব্য যুক্ত করুন।
নরেন্দ্র ভার্মা

@forhas দয়া মধ্য দিয়ে যেতে প্রশ্ন stackoverflow.com/questions/58185249/...
GokulRaj কে এন

46

আপনি সংগ্রহ থেকে কোনও শিশু সত্তা সরিয়ে দেওয়ার মুহুর্তে আপনি সেই শিশু সত্তাকেও ডিবি থেকে সরিয়ে ফেলবেন। orphanRemoval এছাড়াও বোঝায় যে আপনি পিতামাতাকে পরিবর্তন করতে পারবেন না; যদি কোনও বিভাগে কর্মচারী থাকে, আপনি একবার সেই কর্মচারীকে অন্য ডিপ্রেরেশনে রাখার জন্য অপ্রত্যাশিতভাবে সেই কর্মচারীকে ডিবি থেকে ফ্লাশ / কমিটে অপসারণ করবেন (যা প্রথমে আসে)। মনোবলটি এতদিন অনাথ সরানোর কাজটিকে সত্য হিসাবে নির্ধারণ করা হবে যতক্ষণ আপনি নিশ্চিত যে parent পিতামাতার সন্তানরা তাদের অস্তিত্ব জুড়ে কোনও অন্য পিতামাতায় স্থানান্তরিত হবে না। অনাথরেমোভাল চালু করা স্বয়ংক্রিয়ভাবে ক্যাসকেড তালিকায় রিমোভ যোগ করে।


3
ঠিক ঠিক ... একে "ব্যক্তিগত" পিতামাতার / সন্তানের সম্পর্কও বলা হয়।
এইচডিভে

এর অর্থ আমি যত তাড়াতাড়ি কল করি department.remove(emp);যে কর্মচারী এমনকি কল না করেই commit()
এমপ

18

DDL জন্য সমতুল্য JPA ম্যাপিং ON DELETE CASCADEহয় cascade=CascadeType.REMOVE। এতিম অপসারণের অর্থ হ'ল যখন তাদের "পিতামাতার" সত্তার সাথে সম্পর্ক নষ্ট হয়ে যায় তখন নির্ভরশীল সত্তাগুলি সরানো হয়। উদাহরণস্বরূপ, কোনও শিশু যদি @OneToManyকোনও সুনির্দিষ্টভাবে সত্তা পরিচালককে এটি সরিয়ে না নিয়ে কোনও সম্পর্ক থেকে সরানো হয় ।


1
cascade=CascadeType.REMOVEএর সমতুল্য নয় ON DELETE CASCADE। অ্যাপ্লিকেশন কোডটি সরিয়ে ফেলুন এবং ডিবিতে মৃত্যুদণ্ডপ্রাপ্ত অন্যান্য ডিডিএলে প্রভাবিত করে না। দেখুন stackoverflow.com/a/19696859/548473
গ্রেগরি Kislin

9

পার্থক্যটি হ'ল:
- orphanRemoval = সত্য: "শিশু" সত্তাটি যখন আর রেফারেন্স করা হয় তখন সরানো হয় (এর পিতামাতাকে অপসারণ করা যায় না)।
- ক্যাসকেডটাইপ.আমারমোভে: "শিশু" সত্তা কেবল তখনই তার "পিতামাতাকে" সরানো হয়।


6

যেহেতু এটি একটি খুব সাধারণ প্রশ্ন, আমি এই নিবন্ধটি লিখেছি , যার ভিত্তিতে এই উত্তরটি ভিত্তিক।

সত্তার রাষ্ট্রের রূপান্তর

জেপিএ এসকিউএল স্টেটমেন্টগুলিতে সন্নিবেশ, আপডেট বা ডিলিটের মতো সত্তার রাষ্ট্রের রূপান্তরগুলি অনুবাদ করে।

জেপিএ সত্তা রাষ্ট্রের রূপান্তর

যখন আপনি persistকোনও সত্তা, আপনি EntityManagerস্বয়ংক্রিয়ভাবে বা ম্যানুয়ালি ফ্লাশ করা হয় তখন কার্যকর করা INSERT বিবৃতিটি নির্ধারণ করে যাচ্ছেন ।

যখন আপনি removeকোনও সত্তা, আপনি মোছা বিবৃতিটি সময়সূচী করছেন, যা অধ্যবসায় প্রসঙ্গে প্রবর্তিত হলে কার্যকর করা হবে।

ক্যাসকেডিং সত্তা রাষ্ট্রের রূপান্তর

সুবিধার্থে, জেপিএ আপনাকে পিতা-মাতার সত্তা থেকে একের মধ্যে একের জন্য রাষ্ট্রীয় রূপান্তর প্রচার করতে দেয়।

সুতরাং, যদি আপনার কোনও পিতামাতার Postসত্তা থাকে যা শিশু সত্তার সাথে @OneToManyসম্পর্কিত হয় PostComment:

পোস্ট এবং পোস্টকমেন্ট সত্তা

commentsমধ্যে সংগ্রহ Postসত্তা নিম্নরূপ ম্যাপ করা হয়:

@OneToMany(
    mappedBy = "post", 
    cascade = CascadeType.ALL,
    orphanRemoval = true
)
private List<Comment> comments = new ArrayList<>();

CascadeType.ALL

cascadeঅ্যাট্রিবিউট JPA প্রদানকারী বলে পিতা বা মাতা থেকে সত্তা রাষ্ট্র রূপান্তরটি পাস Postসবাইকে সত্তা PostCommentঅন্তর্ভুক্ত সত্ত্বা commentsসংগ্রহ।

সুতরাং, আপনি যদি Postসত্তাটি সরান :

Post post = entityManager.find(Post.class, 1L);
assertEquals(2, post.getComments().size());

entityManager.remove(post);

জেপিএ সরবরাহকারী PostCommentপ্রথমে সত্তাটি সরিয়ে ফেলবে , এবং যখন সমস্ত শিশু সত্তা মুছে ফেলা হবে তখন এটি সত্তাটিও মুছে ফেলবে Post:

DELETE FROM post_comment WHERE id = 1
DELETE FROM post_comment WHERE id = 2

DELETE FROM post WHERE id = 1

এতিম অপসারণ

আপনি যখন orphanRemovalএট্রিবিউটটি সেট করেন true, তখন জেপিএ সরবরাহকারী removeযখন শিশু থেকে সত্তা সংগ্রহ থেকে অপসারণ করা হয় তখন একটি ক্রিয়াকলাপ নির্ধারণ করতে চলেছে ।

সুতরাং, আমাদের ক্ষেত্রে,

Post post = entityManager.find(Post.class, 1L);
assertEquals(2, post.getComments().size());

PostComment postComment = post.getComments().get(0);
assertEquals(1L, postComment.getId());

post.getComments().remove(postComment);

জেপিএ সরবরাহকারী সম্পর্কিত post_commentরেকর্ডটি সরিয়ে ফেলছে যেহেতু সংগ্রহে PostCommentসত্তাটির আর উল্লেখ নেই comments:

DELETE FROM post_comment WHERE id = 1

ক্যাসকেড মুছে ফেলুন

ON DELETE CASCADEএফ কে পর্যায়ে সংজ্ঞায়িত করা হয়:

ALTER TABLE post_comment 
ADD CONSTRAINT fk_post_comment_post_id 
FOREIGN KEY (post_id) REFERENCES post 
ON DELETE CASCADE;

একবার আপনি এটি করেন, আপনি যদি একটি postসারি মুছে ফেলেন:

DELETE FROM post WHERE id = 1

সম্পর্কিত সমস্ত post_commentসত্তা ডাটাবেস ইঞ্জিন দ্বারা স্বয়ংক্রিয়ভাবে সরানো হবে। তবে আপনি ভুল করে কোনও মূল সত্তা মুছলে এটি খুব বিপজ্জনক অপারেশন হতে পারে।

উপসংহার

জেপিএ cascadeএবং orphanRemovalবিকল্পগুলির সুবিধা হ'ল হারিয়ে যাওয়া আপডেটগুলি রোধ করতে আপনি আশাবাদী লকিং থেকেও উপকার পেতে পারেন ।

আপনি যদি জেপিএ ক্যাসকেডিং মেকানিজম ব্যবহার করেন, আপনার ডিডিএল-স্তর ব্যবহার করার দরকার নেই যা আপনি ON DELETE CASCADEএকাধিক স্তরে বহু শিশু সত্তা মূলের সত্তা সরিয়ে ফেললে খুব বিপজ্জনক ক্রিয়াকলাপ হতে পারে।


সুতরাং আপনার উত্তরের অনাথ অপসারণ অংশে: post.getComments ()। অপসারণ (পোস্টকমেন্ট); কেবল পার্সিস্ট ক্যাসকেডের কারণে ওয়ানটোম্যান দ্বিদ্বায়ক ম্যাপিংয়ে কাজ করবে। ক্যানকেডিং ছাড়াই এবং ম্যান্টি টুওনে পক্ষ অপসারণ না করে যেমন আপনার উদাহরণস্বরূপ, 2 টি সত্তার মধ্যে সংযোগ অপসারণ ডিবিতে স্থির থাকবে না?
অরেলিজে

এতিম অপসারণ দ্বারা প্রভাবিত হয় না CascadeType। এটি পরিপূরক প্রক্রিয়া। এখন, আপনি দৃ pers়তা সহ অপসারণের ভুল করছেন। অনাথ অপসারণ হ'ল অযৌক্তিক সমিতিগুলি মুছে ফেলার সময় অবিচ্ছিন্নভাবে নতুন সত্ত্বা সংরক্ষণের বিষয়ে। এই ধারণাগুলি সম্পর্কে আরও ভাল ধারণা পেতে আপনাকে উত্তরের প্রদত্ত লিঙ্কগুলি অনুসরণ করতে হবে।
ভ্লাদ মিহালসিয়া

আমি একটি জিনিস বুঝতে পারি না: আমরা যদি এম এর সাথে সংযোগটি না সরিয়ে রাখি তবে এতিম অপসারণ কীভাবে দ্বিদ্বায়ী ম্যাপিংয়ে লাথি মারবে? আমি মনে করি পোস্টকমেন্ট.পস্ট সেট না করে পোস্টের তালিকা থেকে পোস্টকমেন্ট সরিয়ে ফেললে ডিবিতে থাকা 2 টি সত্তার মধ্যে সংযোগ অপসারণ হবে না। এ কারণেই আমি মনে করি যে অনাথ অপসারণ আরম্ভ করবে না, আপেক্ষিক বিশ্বে পোস্টকমেন্ট এতিম নয়। আমি কিছু ফ্রি সময় পেলে এটি পরীক্ষা করব will
অরেলিজে ২

1
আমি এই দুটি উদাহরণ আমার উচ্চ-পারফরম্যান্স জাভা দৃ Pers়তা গিটহাবের সংগ্রহস্থলে যুক্ত করেছি যা দেখায় যে এটি কীভাবে কাজ করে। আপনাকে সাধারণত সত্ত্বা সরানোর জন্য সাধারণত করণীয় হওয়ায় আপনার সন্তানের পক্ষের সিঙ্ক্রোনাইজ করার দরকার নেই। তবে, অনাথ অপসারণ কেবলমাত্র ক্যাসকেডিং যুক্ত করা হলে কাজ করে তবে এটি জেপিএর নির্দিষ্টকরণ নয়, হাইবারনেট সীমাবদ্ধতা বলে মনে হয়।
ভ্লাদ মিহালসিয়া

5

@GaryK উত্তর একেবারে মহান, আমি এক ঘন্টার কাটিয়েছি হয় একটি ব্যাখ্যা খুঁজছেন orphanRemoval = trueবনাম CascadeType.REMOVEএবং এটি আমাকে বুঝতে সাহায্য করেছে।

সংশ্লেষ: কেবলমাত্র যদি আমরা অবজেক্ট ( ) মুছতে পারি তবেorphanRemoval = true একইরকম কাজ করে এবং আমরা চাই শিশুদের অবজেক্টগুলিও সরানো হোক।CascadeType.REMOVE entityManager.delete(object)

সম্পূর্ণ পৃথক স্থানে, যখন আমরা কিছু তথ্য আনয়ন করি List<Child> childs = object.getChilds()এবং তারপরে কোনও শিশু ( entityManager.remove(childs.get(0)) ব্যবহার করি তখন orphanRemoval=trueতার সাথে সম্পর্কিত সেই সত্তাটি childs.get(0)ডাটাবেস থেকে মুছে ফেলা হবে।


1
আপনার দ্বিতীয় অনুচ্ছেদে একটি টাইপো রয়েছে: এনটিটি ম্যানেজ.আরডিলেট (আপত্তি) এর মতো কোনও পদ্ধতি নেই; এটি অ্যান্টিটি ম্যানেজ.আরমোভ (আপত্তি)।
জেএল_এসও

3

অনাথ অপসারণ নিম্নলিখিত পরিস্থিতিতে যেমন মুছে ফেলা নগদ হিসাবে একই প্রভাব রয়েছে: - আসুন আমরা বলতে পারি যে ছাত্র সত্তা এবং গাইড সত্তার মধ্যে আমাদের অনেকের মধ্যে একটি সহজ সম্পর্ক রয়েছে, যেখানে অনেক শিক্ষার্থী একই গাইডে এবং ডাটাবেসে ম্যাপ করতে পারে আমাদের একটি শিক্ষার্থী এবং গাইড সারণীর মধ্যে বিদেশী কী সম্পর্ক যেমন ছাত্র সারণীর এফকে হিসাবে id_guide রয়েছে।

    @Entity
    @Table(name = "student", catalog = "helloworld")
    public class Student implements java.io.Serializable {
     @Id
     @GeneratedValue(strategy = IDENTITY)
     @Column(name = "id")
     private Integer id;

    @ManyToOne(cascade={CascadeType.PERSIST,CascadeType.REMOVE})
    @JoinColumn(name = "id_guide")
    private Guide guide;

// প্যারেন্ট সত্তা

    @Entity
    @Table(name = "guide", catalog = "helloworld")
    public class Guide implements java.io.Serializable {

/**
 * 
 */
private static final long serialVersionUID = 9017118664546491038L;

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
private Integer id;

@Column(name = "name", length = 45)
private String name;

@Column(name = "salary", length = 45)
private String salary;


 @OneToMany(mappedBy = "guide", orphanRemoval=true) 
 private Set<Student> students = new  HashSet<Student>(0);

এই দৃশ্যে, সম্পর্কটি এমন যে ছাত্র সত্তা সম্পর্কের মালিক এবং যেমন পুরো অবজেক্টের গ্রাফ ধরে রাখতে আমাদের ছাত্র সত্তা সংরক্ষণ করতে হবে যেমন উদাহরণস্বরূপ

    Guide guide = new Guide("John", "$1500");
    Student s1 = new Student(guide, "Roy","ECE");
    Student s2 = new Student(guide, "Nick", "ECE");
    em.persist(s1);
    em.persist(s2);

এখানে আমরা দুটি পৃথক শিক্ষার্থী অবজেক্টের সাথে একই গাইডকে ম্যাপিং করছি এবং যেহেতু CASCADE.PERSIST ব্যবহার করা হয়েছে, অবজেক্ট গ্রাফটি ডাটাবেস টেবিলের নীচে যেমন সংরক্ষণ করা হবে (আমার ক্ষেত্রে MySQL)

শিক্ষার্থীদের টেবিল: -

আইডির নাম ডিপোড আইডি_গুইড

1 রায় ইসিই 1

2 নিক ECE 1

গাইড সারণী: -

আইডি NAME বেতন

1 জন 1500 ডলার

এবং এখন যদি আমি ব্যবহার করে শিক্ষার্থীদের মধ্যে একটি অপসারণ করতে চাই

      Student student1 = em.find(Student.class,1);
      em.remove(student1);

এবং যখন কোনও শিক্ষার্থীর রেকর্ড অপসারণ করা হয় তখন সংশ্লিষ্ট গাইড রেকর্ডটিও মুছে ফেলা উচিত, সেখানেই শিক্ষার্থীর সত্তায় CASCADE.REMOVE বৈশিষ্ট্যটি চিত্রায় আসে এবং এটি কী করে; এটি ছাত্রকে সনাক্তকারী 1 এবং সেই সাথে সম্পর্কিত গাইড অবজেক্ট (শনাক্তকারী) দিয়ে সরিয়ে দেয় 1)। তবে এই উদাহরণে, আরও একটি স্টুডেন্ট অবজেক্ট রয়েছে যা একই গাইড রেকর্ডে ম্যাপ করা হয়েছে এবং যদি না আমরা গাইড সত্তায় অরফ্রেনমোল = সত্য বৈশিষ্ট্যটি ব্যবহার না করি তবে উপরের সরানো কোডটি কাজ করবে না।

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