উত্তর:
থেকে এই ফোরামে পোস্ট
persist()
ভাল সংজ্ঞায়িত করা হয়। এটি একটি ক্ষণস্থায়ী উদাহরণ স্থির করে তোলে। যাইহোক, এটি গ্যারান্টি দেয় না যে সনাক্তকারী মানটি অবিলম্বে অবিচ্ছিন্ন উদাহরণকে বরাদ্দ করা হবে, অ্যাসাইনমেন্টটি ফ্লাশের সময়ে ঘটতে পারে। অনুমানটি এটি বলে না, যা আমার সাথে সমস্যাpersist()
।
persist()
এছাড়াও গ্যারান্টি দেয় যে লেনদেনের সীমানার বাইরে ডাকলে এটি কোনও INSERT বিবৃতি কার্যকর করবে না। এটি একটি বর্ধিত সেশন / অধ্যবসায় প্রসঙ্গের সাথে দীর্ঘ-চলমান কথোপকথনে কার্যকর।মত একটি পদ্ধতি
persist()
প্রয়োজন।
save()
এটির কোনও গ্যারান্টি দেয় না, এটি একটি শনাক্তকারীকে ফিরিয়ে দেয় এবং শনাক্তকারী (যেমন "পরিচয়" জেনারেটর, "সিক্যুয়েন্স" নয়) পেতে যদি কোনও INSERT কার্যকর করা হয়, তবে এই INSERT তত্ক্ষণাত্ ঘটে, আপনি ভিতরে বা বাইরে থাকুক না কেন একটি লেনদেন এটি একটি বর্ধিত সেশন / অধ্যবসায় প্রসঙ্গে একটি দীর্ঘ-চলমান কথোপকথনে ভাল নয়।
আমি আমার স্থানীয় মেশিনে এটি বেশ কয়েকবার চালানো সহ সেভ () বনাম অবিরাম () নিয়ে ভাল গবেষণা করেছি। পূর্ববর্তী সমস্ত ব্যাখ্যা বিভ্রান্তিকর এবং সঠিক নয়। আমি একটি সম্পূর্ণ গবেষণার পরে নীচে সংরক্ষণ () সংরক্ষণ এবং () অবিরত রেখেছি compared
Save()
Serializable
রিটার্ন টাইপ।Persist()
generated id
আপনি যে সত্তাটি চালিয়ে যাচ্ছেন তাকে হস্তান্তর করেsession.persist()
PersistentObjectException
এটি আলাদা না হওয়ার কারণে কোনও বিচ্ছিন্ন বস্তু নিক্ষেপ করবে ।এই সমস্ত চেষ্টা করা / পরীক্ষা করা হয় Hibernate v4.0.1
।
Save()
?
আমি save()
এবং এর মধ্যে পার্থক্য রেকর্ড করতে কিছু মক টেস্টিং করেছি persist()
।
ক্ষণস্থায়ী সত্তার সাথে কাজ করার সময় এই দুটি পদ্ধতির মতোই শব্দগুলি একই রকম আচরণ করে তবে বিচ্ছিন্ন সত্তার সাথে আচরণ করার সময় পৃথক হয়।
নীচের উদাহরণের জন্য, কর্মচারী যানটিকে পিকে সাথে সত্তা হিসাবে গ্রহণ করুন vehicleId
যা উত্পন্ন মান এবং এর vehicleName
অন্যতম বৈশিষ্ট্য।
উদাহরণ 1: ক্ষণস্থায়ী বস্তুর সাথে ডিলিং
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = new EmployeeVehicle();
entity.setVehicleName("Honda");
session.save(entity);
// session.persist(entity);
session.getTransaction().commit();
session.close();
ফলাফল:
select nextval ('hibernate_sequence') // This is for vehicle Id generated : 36
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Honda, 36)
আপনি ইতিমধ্যে স্থায়ী অবজেক্ট পেলে এবং সংরক্ষণ করে ফলাফলটি একই হিসাবে নোট করুন
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
entity.setVehicleName("Toyota");
session.save(entity); -------> **instead of session.update(entity);**
// session.persist(entity);
একই ব্যবহার করে পুনরাবৃত্তি করুন persist(entity)
এবং ফলাফলটি নতুন আইডির সাথে একই হবে (বলুন 37, হোন্ডা);
উদাহরণ 2: বিচ্ছিন্ন অবজেক্টের সাথে ডিলিং
// Session 1
// Get the previously saved Vehicle Entity
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
session.close();
// Session 2
// Here in Session 2 , vehicle entity obtained in previous session is a detached object and now we will try to save / persist it
// (i) Using Save() to persist a detached object
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.save(entity);
session2.getTransaction().commit();
session2.close();
ফলাফল: আপনি সম্ভবত আইডির সাথে যানটির প্রত্যাশা করতে পারেন: ৩ previous পূর্ববর্তী সেশনে প্রাপ্ত "টয়োটা" নামে নাম আপডেট করা হয়েছে। তবে যা ঘটে তা হ'ল ডিবিতে একটি নতুন সত্তা সংরক্ষিত হয়েছে যার জন্য নতুন আইডি তৈরি করা হয়েছে এবং "টয়োটা" নামকরণ করা হয়েছে
select nextval ('hibernate_sequence')
insert into Employee_Vehicle ( Vehicle_Name, Vehicle_Id) values ( Toyota, 39)
বিচ্ছিন্ন সত্তা অব্যাহত রাখতে ব্যবহার করা ist
// (ii) Using Persist() to persist a detached
// Session 1
Session session = factory.openSession();
session.beginTransaction();
EmployeeVehicle entity = (EmployeeVehicle)session.get(EmployeeVehicle.class, 36);
session.close();
// Session 2
// Here in Session 2 , vehicle entity obtained in previous session is a detached object and now we will try to save / persist it
// (i) Using Save() to persist a detached
Session session2 = factory.openSession();
session2.beginTransaction();
entity.setVehicleName("Toyota");
session2.persist(entity);
session2.getTransaction().commit();
session2.close();
ফলাফল:
Exception being thrown : detached entity passed to persist
সুতরাং, ট্রান্সিয়েন্ট অবজেক্টের সাথে ডিল করার সময় সেভটি সাবধানতার সাথে ব্যবহার করা উচিত সেভ () এর চেয়ে পার্সিস্ট () ব্যবহার করা সর্বদা ভাল।
গুরুত্বপূর্ণ দ্রষ্টব্য: উপরের উদাহরণে, যানবাহনের সত্তার pk একটি উত্পন্ন মান, সুতরাং বিচ্ছিন্ন সত্তা অবিরত রাখতে সেভ () ব্যবহার করার সময় হাইবারনেট স্থির রাখতে নতুন আইডি উত্পন্ন করে। তবে যদি এই পিকে কোনও উত্পন্ন মান না হয় তবে এর ব্যতিক্রম হিসাবে উল্লেখযোগ্য ব্যতিক্রমী ব্যতিরেকে ফলাফল পাওয়া যায়।
হাইবারনেটে বিভিন্ন জেদী পদ্ধতি সম্পর্কে এই প্রশ্নের কয়েকটি ভাল উত্তর রয়েছে। আপনার প্রশ্নের সরাসরি উত্তর দিতে, সংরক্ষণ () সহ সন্নিবেশ বিবৃতিটি লেনদেনের অবস্থা নির্বিশেষে অবিলম্বে কার্যকর করা হয়। এটি keyোকানো কীটি ফিরিয়ে দেয় যাতে আপনি এরকম কিছু করতে পারেন:
long newKey = session.save(myObj);
সুতরাং আপনার যদি অবিলম্বে অধ্যবসায়ের ঘটনায় নির্ধারিত কোনও শনাক্তকারী প্রয়োজন হয় তবে সেভ () ব্যবহার করুন।
অবিচল () সহ, সন্নিবেশ বিবৃতিটি একটি লেনদেনে কার্যকর করা হয়, তাত্ক্ষণিকভাবে প্রয়োজন হয় না। এটি বেশিরভাগ ক্ষেত্রেই পছন্দনীয়।
লেনদেনের সাথে ক্রম-সিকুয়েন্স হওয়ার জন্য যদি সন্নিবেশের প্রয়োজন না হয় এবং আপনার keyোকানো কীটি দরকার হয় না তবে অবিরত () ব্যবহার করুন।
এখানে পার্থক্যগুলি যা আপনাকে অবিচল থাকার সুবিধা এবং পদ্ধতিগুলি সংরক্ষণ করতে সহায়তা করতে পারে:
অবিচ্ছিন্ন () পদ্ধতিটি গ্যারান্টি দেয় না যে সনাক্তকারী মানটি অবিলম্বে স্থির অবস্থায় অর্পণ করা হবে, অ্যাসাইনমেন্টটি ফ্লাশের সময়ে ঘটতে পারে।
ক্রমাগত () পদ্ধতিটি যদি লেনদেনের সীমানার বাইরে বলা হয় তবে একটি সন্নিবেশ ক্যোয়ারী কার্যকর করবে না। যখন, সংরক্ষণ () পদ্ধতিটি একটি শনাক্তকারীকে ফেরত দেয় যাতে শনাক্তকরণের জন্য একটি সন্নিবেশ ক্যোয়ারী তাত্ক্ষণিকভাবে কার্যকর করা হয়, এটি কোনও লেনদেনের ভিতরে বা বাইরে থাকুক না কেন।
অবিচ্ছিন্ন পদ্ধতিটি লেনদেনের সীমানার বাইরে বলা হয়, এটি একটি বর্ধিত সেশন প্রসঙ্গে দীর্ঘ-চলমান কথোপকথনে কার্যকর। অন্যদিকে বর্ধিত অধিবেশন প্রসঙ্গে একটি দীর্ঘ-চলমান কথোপকথনে সংরক্ষণের পদ্ধতিটি ভাল নয়।
হাইবারনেটে সংরক্ষণ এবং অবিচলিত পদ্ধতির মধ্যে পঞ্চম পার্থক্য: জেপিএ দ্বারা অবিরাম সমর্থন করা হয়, তবে সেভ কেবলমাত্র হাইবারনেট দ্বারা সমর্থিত।
হাইবারনেটে সংরক্ষণ এবং অবিচলিত পদ্ধতির মধ্যে পার্থক্য পোস্ট থেকে আপনি সম্পূর্ণ কার্যকারী উদাহরণটি দেখতে পাচ্ছেন
save () - পদ্ধতির নাম অনুসারে, হাইবারনেট সেভ () ব্যবহার করে ডাটাবেসে সত্তা সংরক্ষণ করতে পারেন। আমরা কোনও লেনদেনের বাইরে এই পদ্ধতিটি করতে পারি। আমরা যদি লেনদেন ছাড়াই এটি ব্যবহার করি এবং আমাদের সত্তার মধ্যে ক্যাসকেডিং থাকে, তবে আমরা সেশনটি ফ্লাশ না করে কেবলমাত্র প্রাথমিক সত্ত্বাটি সংরক্ষণ করা হবে।
persist () - হাইবারনেট সিস্টিভ সংরক্ষণের মতোই (লেনদেনের সাথে) এবং এটি অবিচ্ছিন্ন প্রসঙ্গটিতে সত্তা অবজেক্টটিকে যুক্ত করে, যাতে আরও কোনও পরিবর্তন ট্র্যাক করা হয়। লেনদেন প্রতিশ্রুতিবদ্ধ হওয়ার আগে বা সেশন ফ্লাশ করার আগে যদি অবজেক্টের বৈশিষ্ট্যগুলি পরিবর্তন করা হয় তবে এটি ডাটাবেসেও সংরক্ষণ করা হবে। এছাড়াও, আমরা কেবলমাত্র একটি লেনদেনের সীমানার মধ্যেই স্থির () পদ্ধতি ব্যবহার করতে পারি, সুতরাং এটি নিরাপদ এবং কোনও ক্যাসকেডযুক্ত বস্তুর যত্ন নেয়। শেষ অবধি, জাস্টিস্ট কিছুই ফিরিয়ে দেয় না যাতে উত্পন্ন শনাক্তকরণের মানটি পেতে আমাদের স্থির অবজেক্টটি ব্যবহার করা দরকার।
এখানে পার্থক্য:
সংরক্ষণ:
জিদ:
বেসিক নিয়ম বলে যে:
উত্পন্ন সনাক্তকারী সহ সত্তার জন্য:
সংরক্ষণ (): এটি অবিরত বস্তুকে অবিচ্ছিন্ন করা ছাড়াও কোনও সত্তার সনাক্তকারীকে তাত্ক্ষণিকভাবে প্রদান করে। সুতরাং একটি সন্নিবেশ জিজ্ঞাসা অবিলম্বে বরখাস্ত করা হয়।
persist (): এটি অবিচ্ছিন্ন বস্তুটি প্রদান করে। এটি তাত্ক্ষণিকভাবে শনাক্তকারীকে ফিরিয়ে দেওয়ার কোনও বাধ্যবাধকতা রাখে না তাই এটি guaranteeোকানো অবিলম্বে বরখাস্ত করা হবে বলে গ্যারান্টি দেয় না fired এটি তাত্ক্ষণিকভাবে একটি fireোকান চালিত করতে পারে তবে এটির গ্যারান্টি নেই। কিছু ক্ষেত্রে কোয়েরিটি তাত্ক্ষণিকভাবে বরখাস্ত করা যেতে পারে অন্যদিকে এটি সেশনের ফ্লাশ সময়ে চালিত হতে পারে।
নির্ধারিত শনাক্তকারী সহ সত্তার জন্য:
সংরক্ষণ (): এটি অবিলম্বে কোনও সত্তার সনাক্তকারীকে ফিরিয়ে দেয়। যেহেতু সনাক্তকারীটিকে ইতিমধ্যে সংরক্ষণ কল করার আগে সত্তাকে বরাদ্দ করা হয়েছে, তাই সন্নিবেশটি সঙ্গে সঙ্গে বরখাস্ত করা হবে না। এটি সেশন ফ্লাশের সময় চালিত হয়।
অব্যাহত (): সংরক্ষণ হিসাবে একই। এটি ফ্লাশ সময়ে sertোকানো আগুন।
ধরুন আমাদের একটি সত্তা রয়েছে যা একটি উত্পন্ন সনাক্তকারী ব্যবহার করে যা নিম্নলিখিতভাবে:
@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
@Id
@Column(name = "USER_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
private int userId;
@Column(name = "USER_NAME")
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
সংরক্ষণ() :
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserName("Gaurav");
session.save(user); // Query is fired immediately as this statement is executed.
session.getTransaction().commit();
session.close();
অবিরত ():
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserName("Gaurav");
session.persist(user); // Query is not guaranteed to be fired immediately. It may get fired here.
session.getTransaction().commit(); // If it not executed in last statement then It is fired here.
session.close();
এখন ধরা যাক, এনডিটেশন উত্পন্ন করে আইডি ক্ষেত্র ব্যতীত আমাদের একই সত্তা নীচের মতো সংজ্ঞায়িত করা হয়েছে, আইডি ম্যানুয়ালি নির্ধারিত হবে।
@Entity
@Table(name="USER_DETAILS")
public class UserDetails {
@Id
@Column(name = "USER_ID")
private int userId;
@Column(name = "USER_NAME")
private String userName;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
সংরক্ষণের জন্য ():
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Gaurav");
session.save(user); // Query is not fired here since id for object being referred by user is already available. No query need to be fired to find it. Data for user now available in first level cache but not in db.
session.getTransaction().commit();// Query will be fired at this point and data for user will now also be available in DB
session.close();
অবিরত জন্য ():
Session session = sessionFactory.openSession();
session.beginTransaction();
UserDetails user = new UserDetails();
user.setUserId(1);
user.setUserName("Gaurav");
session.persist(user); // Query is not fired here.Object is made persistent. Data for user now available in first level cache but not in db.
session.getTransaction().commit();// Query will be fired at this point and data for user will now also be available in DB
session.close();
উপরোক্ত মামলাগুলি সত্য ছিল যখন কোনও লেনদেনের মধ্যে থেকে সংরক্ষণ বা অবিরাম বলা হয়েছিল।
সংরক্ষণ এবং অবিচলিত মধ্যে পার্থক্য অন্যান্য পয়েন্টগুলি হল:
save () কে লেনদেনের বাইরে বলা যেতে পারে। যদি নির্ধারিত শনাক্তকারী ব্যবহার করা হয় তবে যেহেতু আইডি ইতিমধ্যে উপলব্ধ, তাই কোনও queryোকানো কোয়েরি অবিলম্বে বরখাস্ত করা হবে না। সেশনটি ফ্লাশ করা হলেই ক্যোয়ারি বরখাস্ত করা হয়।
যদি জেনারেটেড আইডেন্টিফায়ার ব্যবহার করা হয়, তবে আইডি তৈরির প্রয়োজন হয় তাই সন্নিবেশ অবিলম্বে বরখাস্ত করা হয়। তবে এটি কেবল প্রাথমিক সত্তাকেই সংরক্ষণ করে। সত্তার যদি কিছু ক্যাসকেড সত্তা থাকে তবে সেগুলি এই মুহুর্তে ডিবিতে সংরক্ষণ করা হবে না। সেশনটি ফ্লাশ করা হলে সেগুলি সংরক্ষণ করা হবে।
যদি অবিচল থাকে () কোনও লেনদেনের বাইরে থাকে তবে সেশনটি কেবল তখনই চালিত হয় যখন কোনও ধরণের সনাক্তকারী (উত্পন্ন বা নির্ধারিত) ব্যবহৃত হয় না কেন সেশনটি ফ্লাশ করা হয় fl
যদি অবিচ্ছিন্ন বস্তুতে যদি সেভকে ডাকা হয়, তবে সত্তা আপডেট ক্যোয়ারী ব্যবহার করে সংরক্ষণ করা হয়।
আসলে, হাইবারনেট সেভ () এবং অব্যাহত রাখার () পদ্ধতির মধ্যে পার্থক্যটি আমরা ব্যবহার করছি জেনারেটর শ্রেণীর উপর নির্ভর করে।
তবে এখানে বিষয়টি সংরক্ষণ করুন () পদ্ধতিটি হাইবারনেট দ্বারা উত্পাদিত প্রাথমিক কী আইডি মানটি ফিরিয়ে আনতে পারে এবং আমরা এটিকে
দীর্ঘ এস = সেশন.সভে (কে) দ্বারা দেখতে পাই ;
এই একই ক্ষেত্রে, অবিচল () ক্লায়েন্টকে কোনও মূল্য ফেরত দেবে না, রিটার্ন টাইপ শূন্য করে।
অব্যাহত রাখুন () এছাড়াও গ্যারান্টি দেয় যে এটি কোনও INSERT বিবৃতি কার্যকর করে না যদি এটি লেনদেনের সীমানার বাইরে বলা হয়।
() সংরক্ষণের ক্ষেত্রে, INSERT অবিলম্বে ঘটে যায়, আপনি কোনও লেনদেনের অভ্যন্তরে বা বাইরে থাকুক না কেন।
যদি আমাদের জেনারেটর শ্রেণি নির্ধারিত হয়, তবে সংরক্ষণ () এবং অব্যাহত () পদ্ধতির মধ্যে কোনও পার্থক্য নেই। কারণ জেনারেটর 'অ্যাসাইনড' অর্থ, প্রোগ্রামার হিসাবে আমাদের অবশ্যই ডাটাবেসে সংরক্ষণের জন্য প্রাথমিক কী মানটি দিতে হবে [আশা করি আপনি এই জেনারেটর ধারণাটি জানেন] নির্ধারিত জেনারেটর শ্রেণি ব্যতীত অন্য ক্ষেত্রে, ধরুন আমাদের জেনারেটর শ্রেণির নাম বর্ধনের অর্থ হাইবারনেট নিজেই প্রাইমারি কী আইডি মানটি ডাটাবেসে ডানদিকে ডেকে দেবে [নির্ধারিত জেনারেটর ব্যতীত, হাইবারনেট কেবল প্রাথমিক কী আইডি মান মনে রাখার জন্য যত্ন নেওয়ার জন্য ব্যবহৃত হয়], তাই এই ক্ষেত্রে যদি আমরা সংরক্ষণ () বা অব্যাহত () পদ্ধতি কল করি, এটি সাধারণত ডাটাবেসে রেকর্ডটি প্রবেশ করিয়ে দেবে।
এটি কোনও জেনারেটিকে সংরক্ষণ করার সময় আইডি তে "জেনারেটর" টাইপের ভিত্তিতে সম্পূর্ণরূপে উত্তর দেয়। জেনারেটরের মান যদি "বরাদ্দ করা হয়" যার অর্থ আপনি আইডি সরবরাহ করছেন। তারপরে এটি সংরক্ষণ বা অস্তিত্বের জন্য হাইবারনেটে কোনও পার্থক্য করে না। আপনি যে কোনও পদ্ধতিতে যেতে পারেন। মানটি যদি "নির্ধারিত" না হয় এবং আপনি সেভ () ব্যবহার করেন তবে আপনি সংরক্ষণ () অপারেশন থেকে ফিরে হিসাবে আইডি পাবেন।
অন্য চেকটি হ'ল আপনি যদি লেনদেনের সীমা ছাড়াই অপারেশন করছেন বা না করছেন। কারণ অবিচল () হাইপারনেটের জন্য () সংরক্ষণ করার সময় জেপিএ সম্পর্কিত। সুতরাং লেনদেনের সীমানার বাইরে স্থির () ব্যবহার করে তা করার অনুমতি দেয় না এবং স্টেস্টিস্টের সাথে সম্পর্কিত ব্যতিক্রম ছুঁড়ে দেওয়া হয়। সেভ () এর সাথে থাকাকালীন এ জাতীয় কোনও বিধিনিষেধ নেই এবং লেনদেনের সীমা ছাড়িয়ে কেউ সেভ () এর মাধ্যমে ডিবি লেনদেনের সাথে যেতে পারে।