আমি যেমন এই নিবন্ধে ব্যাখ্যা করেছি , আপনার বেশিরভাগ সময় জেপিএ পদ্ধতি এবং update
ব্যাচের প্রক্রিয়াকরণ কাজের জন্য পছন্দ করা উচিত ।
একটি জেপিএ বা হাইবারনেট সত্তা নিম্নলিখিত চারটি রাজ্যের একটিতে থাকতে পারে:
- ক্ষণস্থায়ী (নতুন)
- পরিচালিত (অবিচলিত)
- বিচ্ছিন্ন
- সরানো (মুছে ফেলা)
এক থেকে অন্য রাজ্যে স্থানান্তরটি সত্ত্বা ম্যানেজার বা সেশন পদ্ধতিগুলির মাধ্যমে সম্পন্ন হয়।
উদাহরণস্বরূপ, জেপিএ EntityManager
নিম্নলিখিত সত্তার রাষ্ট্রের রূপান্তর পদ্ধতি সরবরাহ করে।
হাইবারনেট Session
সমস্ত জেপিএ EntityManager
পদ্ধতি প্রয়োগ করে এবং কিছু অতিরিক্ত সত্তা রাষ্ট্রের রূপান্তর পদ্ধতি যেমন save
, saveOrUpdate
এবং সরবরাহ করে update
।
জিদ করা
অস্থায়ী (নতুন) থেকে পরিচালিত (বহিরাগত) এ সত্তার অবস্থার পরিবর্তন করতে আমরা ব্যবহার করতে পারি persist
জেপিএ দ্বারা প্রদত্ত পদ্ধতিটিEntityManager
যা হাইবারনেট দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত Session
।
persist
পদ্ধতি ট্রিগার একটিPersistEvent
যার দ্বারা পরিচালিত হয় DefaultPersistEventListener
হাইবারনেট ঘটনা শ্রোতা।
অতএব, নিম্নলিখিত পরীক্ষার কেসটি কার্যকর করার সময়:
doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
entityManager.persist(book);
LOGGER.info(
"Persisting the Book entity with the id: {}",
book.getId()
);
});
হাইবারনেট নিম্নলিখিত এসকিউএল বিবৃতি উত্পন্ন করে:
CALL NEXT VALUE FOR hibernate_sequence
-- Persisting the Book entity with the id: 1
INSERT INTO book (
author,
isbn,
title,
id
)
VALUES (
'Vlad Mihalcea',
'978-9730228236',
'High-Performance Java Persistence',
1
)
লক্ষ্য করুন যে বর্তমান অধ্যবসায় প্রসঙ্গে সত্তা id
সংযুক্ত করার আগে নিয়োগ করা হয়েছে Book
। এটির প্রয়োজন হয় কারণ পরিচালিত সত্তাগুলি একটিতে সংরক্ষণ করা হয়Map
কাঠামোতে যেখানে কীটি সত্তার প্রকার এবং তার শনাক্তকারী দ্বারা তৈরি করা হয় এবং মানটি সত্তা রেফারেন্স। এই কারণেই জেপিএ EntityManager
এবং হাইবারনেট Session
প্রথম-স্তরের ক্যাশে হিসাবে পরিচিত।
কল করার সময় persist
, সত্তাটি কেবল বর্তমানে চলমান পার্সিস্টান প্রসঙ্গে যুক্ত থাকে এবং INSERT flush
ডাকা না হওয়া পর্যন্ত স্থগিত করা যায় ।
একমাত্র ব্যতিক্রম হ'ল পরিচয় জেনারেটর যা এই মুহুর্তে সন্নিবেশটিকে ট্রিগার করে যেহেতু সত্তা সনাক্তকারী হিসাবে এটি পাওয়া যায় way এই কারণে, হাইবারনেট পরিচয় জেনারেটর ব্যবহার করে সত্তার জন্য সন্নিবেশগুলি ব্যাচ করতে পারে না। এই বিষয় সম্পর্কে আরও তথ্যের জন্য, চেক আউট এই নিবন্ধটি দেখুন ।
সংরক্ষণ
হাইবারনেট-নির্দিষ্ট save
পদ্ধতিটি জেপিএর পূর্বাভাস দেয় এবং হাইবারনেট প্রকল্পের শুরু থেকেই এটি উপলব্ধ।
save
পদ্ধতি আরম্ভ করে SaveOrUpdateEvent
যার দ্বারা পরিচালিত হয় DefaultSaveOrUpdateEventListener
হাইবারনেট ঘটনা শ্রোতা। অতএব, save
পদ্ধতি সমতূল্য update
এবংsaveOrUpdate
পদ্ধতির ।
save
পদ্ধতিটি কীভাবে কাজ করে তা দেখতে নিম্নলিখিত পরীক্ষার ক্ষেত্রে বিবেচনা করুন:
doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
Session session = entityManager.unwrap(Session.class);
Long id = (Long) session.save(book);
LOGGER.info(
"Saving the Book entity with the id: {}",
id
);
});
উপরের পরীক্ষার কেসটি চালানোর সময় হাইবারনেট নিম্নলিখিত এসকিউএল বিবৃতি উত্পন্ন করে:
CALL NEXT VALUE FOR hibernate_sequence
-- Saving the Book entity with the id: 1
INSERT INTO book (
author,
isbn,
title,
id
)
VALUES (
'Vlad Mihalcea',
'978-9730228236',
'High-Performance Java Persistence',
1
)
আপনি দেখতে পাচ্ছেন, ফলাফলটি persist
পদ্ধতি কলের মতো ident তবে, অসদৃশ persist
,save
পদ্ধতিটি সত্তা শনাক্তকারীকে দেয়।
আরও তথ্যের জন্য, এই নিবন্ধটি দেখুন ।
হালনাগাদ
হাইবারনেট-নির্দিষ্ট update
পদ্ধতিটি বোঝানো হচ্ছে নোংরা চেকিং মেকানিজমকে বাইপাস করা এবং ফ্লাশের সময় কোনও সত্তা আপডেট জোর করে।
update
পদ্ধতি আরম্ভ করে SaveOrUpdateEvent
যার দ্বারা পরিচালিত হয় DefaultSaveOrUpdateEventListener
হাইবারনেট ঘটনা শ্রোতা। সুতরাং, update
পদ্ধতিটি save
এবংsaveOrUpdate
পদ্ধতির সমান ।
update
পদ্ধতিটি কীভাবে কাজ করে তা নীচের উদাহরণটিকে বিবেচনা করে যা কোনও Book
লেনদেনে সত্তা অব্যাহত রাখে , তারপরে সত্তাটি বিচ্ছিন্ন অবস্থায় থাকা অবস্থায় এটি সংশোধন করে এবং update
পদ্ধতি কলটি ব্যবহার করে এটি এসকিউএল আপডেটের দিকে বাধ্য করে ।
Book _book = doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
entityManager.persist(book);
return book;
});
LOGGER.info("Modifying the Book entity");
_book.setTitle(
"High-Performance Java Persistence, 2nd edition"
);
doInJPA(entityManager -> {
Session session = entityManager.unwrap(Session.class);
session.update(_book);
LOGGER.info("Updating the Book entity");
});
উপরের পরীক্ষার কেসটি কার্যকর করার সময় হাইবারনেট নিম্নলিখিত এসকিউএল বিবৃতি উত্পন্ন করে:
CALL NEXT VALUE FOR hibernate_sequence
INSERT INTO book (
author,
isbn,
title,
id
)
VALUES (
'Vlad Mihalcea',
'978-9730228236',
'High-Performance Java Persistence',
1
)
-- Modifying the Book entity
-- Updating the Book entity
UPDATE
book
SET
author = 'Vlad Mihalcea',
isbn = '978-9730228236',
title = 'High-Performance Java Persistence, 2nd edition'
WHERE
id = 1
লক্ষ্য করুন যে প্রতিশ্রুতি দেওয়ার UPDATE
ঠিক পূর্বে দৃistence়তা কনটেক্সট ফ্লাশ চলাকালীন মৃত্যুদন্ড কার্যকর করা হয়েছিল এবং সে কারণেইUpdating the Book entity
বার্তাটি প্রথমে লগ হয়।
ব্যবহার @SelectBeforeUpdate
অপ্রয়োজনীয় আপডেটগুলি এড়াতে করা
এখন, আপডেট আপডেট সর্বদা কার্যকর করা হবে এমনকি সত্তাটি বিচ্ছিন্ন অবস্থায় থাকা অবস্থায় পরিবর্তিত না হলেও। এটি প্রতিরোধ করতে, আপনি @SelectBeforeUpdate
হাইবারনেট টীকাগুলি ব্যবহার করতে পারেন যা একটি SELECT
বিবৃতি ট্রিগার করবে loaded state
যা পরে নোংরা চেকিং প্রক্রিয়া দ্বারা ব্যবহৃত হয়।
সুতরাং, আমরা যদি টীকাটি Book
দিয়ে সত্তাটি @SelectBeforeUpdate
টীকায়িত করি:
@Entity(name = "Book")
@Table(name = "book")
@SelectBeforeUpdate
public class Book {
//Code omitted for brevity
}
এবং নিম্নলিখিত পরীক্ষার কেস কার্যকর করুন:
Book _book = doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
entityManager.persist(book);
return book;
});
doInJPA(entityManager -> {
Session session = entityManager.unwrap(Session.class);
session.update(_book);
});
হাইবারনেট নিম্নলিখিত এসকিউএল স্টেটমেন্টগুলি সম্পাদন করে:
INSERT INTO book (
author,
isbn,
title,
id
)
VALUES (
'Vlad Mihalcea',
'978-9730228236',
'High-Performance Java Persistence',
1
)
SELECT
b.id,
b.author AS author2_0_,
b.isbn AS isbn3_0_,
b.title AS title4_0_
FROM
book b
WHERE
b.id = 1
লক্ষ্য করুন যে, UPDATE
হাইবারনেট নোংরা চেকিং প্রক্রিয়াটি আবিষ্কার করেছে যে সত্তাটি পরিবর্তন করা হয়নি since
SaveOrUpdate
হাইবারনেট-নির্দিষ্ট saveOrUpdate
পদ্ধতিটি কেবলমাত্র একটি উপনাম save
এবং এর জন্য update
।
saveOrUpdate
পদ্ধতি আরম্ভ করে SaveOrUpdateEvent
যার দ্বারা পরিচালিত হয় DefaultSaveOrUpdateEventListener
হাইবারনেট ঘটনা শ্রোতা। সুতরাং, update
পদ্ধতিটি save
এবংsaveOrUpdate
পদ্ধতির সমান ।
এখন, আপনি saveOrUpdate
যখন কোনও সত্তাকে অবিচল থাকতে চান বা UPDATE
নীচের উদাহরণ দ্বারা চিত্রিত হিসাবে জোর করতে চান তখন আপনি ব্যবহার করতে পারেন ।
Book _book = doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(book);
return book;
});
_book.setTitle("High-Performance Java Persistence, 2nd edition");
doInJPA(entityManager -> {
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(_book);
});
সাবধান NonUniqueObjectException
একটা সমস্যা যে সঙ্গে ঘটতে পারে save
, update
এবং saveOrUpdate
যদি অধ্যবসায় প্রসঙ্গ ইতিমধ্যে একই আইডি-র এবং নিম্নলিখিত উদাহরণ হিসাবে একই ধরণের একটি সত্তা রেফারেন্স রয়েছে:
Book _book = doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(book);
return book;
});
_book.setTitle(
"High-Performance Java Persistence, 2nd edition"
);
try {
doInJPA(entityManager -> {
Book book = entityManager.find(
Book.class,
_book.getId()
);
Session session = entityManager.unwrap(Session.class);
session.saveOrUpdate(_book);
});
} catch (NonUniqueObjectException e) {
LOGGER.error(
"The Persistence Context cannot hold " +
"two representations of the same entity",
e
);
}
এখন, উপরোক্ত পরীক্ষার কেসটি কার্যকর করার সময়, হাইবারনেট একটি নিক্ষেপ করতে চলেছে NonUniqueObjectException
কারণ দ্বিতীয়টিতে EntityManager
ইতিমধ্যে Book
একই শনাক্তকারীর সাথে একটি সত্তা রয়েছে যা আমরা পাস করেছি update
এবং পার্সিস্টি কনটেক্সট একই সত্তার দুটি উপস্থাপনা রাখতে পারে না।
org.hibernate.NonUniqueObjectException:
A different object with the same identifier value was already associated with the session : [com.vladmihalcea.book.hpjp.hibernate.pc.Book#1]
at org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext.java:651)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:284)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:227)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:92)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:682)
at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:674)
একত্রিত করা
এড়াতে NonUniqueObjectException
, আপনাকে merge
জেপিএ দ্বারা প্রদত্ত পদ্ধতিটি EntityManager
এবং হাইবারনেট দ্বারা উত্তরাধিকারসূত্রেও ব্যবহার Session
করা উচিত।
এই নিবন্ধে বর্ণিত হিসাবে , merge
পার্সিস্ট্যান্স প্রসঙ্গে যদি কোনও সত্তার রেফারেন্স না পাওয়া যায় তবে এটি ডাটাবেস থেকে একটি নতুন সত্তার স্ন্যাপশট নিয়ে আসে এবং এটি merge
পদ্ধতিতে পাস হওয়া বিচ্ছিন্ন সত্তার অবস্থার অনুলিপি করে ।
merge
পদ্ধতি আরম্ভ করেMergeEvent
যার দ্বারা পরিচালিত হয় DefaultMergeEventListener
হাইবারনেট ঘটনা শ্রোতা।
merge
পদ্ধতিটি কীভাবে কাজ করে তা নীচের উদাহরণটিকে বিবেচনা করে যা কোনও Book
লেনদেনে সত্তা অব্যাহত থাকে , তারপরে সত্তাটি বিচ্ছিন্ন অবস্থায় থাকা অবস্থায় এটি সংশোধন করে এবং বিচ্ছিন্ন অস্তিত্বটিকে merge
একটি পরের দৃistence়তা প্রসঙ্গে পাঠায়।
Book _book = doInJPA(entityManager -> {
Book book = new Book()
.setIsbn("978-9730228236")
.setTitle("High-Performance Java Persistence")
.setAuthor("Vlad Mihalcea");
entityManager.persist(book);
return book;
});
LOGGER.info("Modifying the Book entity");
_book.setTitle(
"High-Performance Java Persistence, 2nd edition"
);
doInJPA(entityManager -> {
Book book = entityManager.merge(_book);
LOGGER.info("Merging the Book entity");
assertFalse(book == _book);
});
উপরোক্ত পরীক্ষার মামলাটি চালানোর সময়, হাইবারনেট নিম্নলিখিত এসকিউএল বিবৃতি কার্যকর করে:
INSERT INTO book (
author,
isbn,
title,
id
)
VALUES (
'Vlad Mihalcea',
'978-9730228236',
'High-Performance Java Persistence',
1
)
-- Modifying the Book entity
SELECT
b.id,
b.author AS author2_0_,
b.isbn AS isbn3_0_,
b.title AS title4_0_
FROM
book b
WHERE
b.id = 1
-- Merging the Book entity
UPDATE
book
SET
author = 'Vlad Mihalcea',
isbn = '978-9730228236',
title = 'High-Performance Java Persistence, 2nd edition'
WHERE
id = 1
লক্ষ্য করুন যে সত্তার রেফারেন্সটি merge
দিয়ে দেওয়া হয়েছে তা merge
পদ্ধতিটিতে আমরা যে আলাদা করেছি তার চেয়ে আলাদা ।
এখন, যদিও merge
বিচ্ছিন্ন সত্তার স্থিতি অনুলিপি করার সময় আপনার জেপিএ ব্যবহার পছন্দ করা উচিত, তবুও SELECT
ব্যাচ প্রসেসিংয়ের কার্য সম্পাদন করার সময় অতিরিক্ত সমস্যা হতে পারে।
এই কারণে, আপনার ব্যবহার পছন্দ করা উচিত update
যখন আপনি নিশ্চিত হন যে ইতিমধ্যে চলমান দৃ .়পদ প্রসঙ্গে ইতিমধ্যে কোনও সত্তা রেফারেন্স সংযুক্ত নেই এবং পৃথক পৃথক উপাদানটি সংশোধন করা হয়েছে।
এই বিষয় সম্পর্কে আরও তথ্যের জন্য, এই নিবন্ধটি দেখুন ।
উপসংহার
কোনও সত্তা অবিরত রাখতে, আপনার জেপিএ persist
পদ্ধতিটি ব্যবহার করা উচিত । বিচ্ছিন্ন সত্তা রাষ্ট্র অনুলিপি করতে, merge
পছন্দ করা উচিত। update
পদ্ধতি ব্যাচ প্রসেসিং কর্ম শুধুমাত্র দরকারী। save
এবং saveOrUpdate
মাত্র alias লেখা হয় update
এবং আপনি সম্ভবত সব সময়ে তাদের ব্যবহার করা উচিত নয়।
save
সত্তা ইতিমধ্যে পরিচালনা করা হলেও কিছু বিকাশকারী কল করে , কিন্তু এটি একটি ভুল এবং পরিচালিত সংস্থাগুলির জন্য, আপডেটটি স্বয়ংক্রিয়ভাবে পার্সিটি কনটেক্স ফ্ল্যাশ সময় পরিচালিত হয়।
আরও তথ্যের জন্য, এই নিবন্ধটি দেখুন ।