হাইবারনেট - ব্যাচ আপডেট আপডেট থেকে অপ্রত্যাশিত সারি গণনা ফিরিয়েছে: 0 প্রকৃত সারি গণনা: 0 প্রত্যাশিত: 1


141

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

org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
        at org.hibernate.jdbc.BatchingBatcher.checkRowCount(BatchingBatcher.java:93)
        at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:79)
        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
        at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransacti
onManager.java:500)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManag
er.java:473)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(Transaction
AspectSupport.java:267)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)

আপনাকে ধন্যবাদ পিটার মর্টেনসেন। আমি আমার ইমেল আপডেট করেছি।
সুজি

আমি একই সমস্যা আছে। এটি খুব বেশি সমস্যা হয় না কারণ এটি খুব কমই ঘটে happens Show_sql ব্যবহার করা ব্যবহারিক নয় কারণ এই আচরণটির পুনরুত্পাদন করতে কয়েক মিলিয়ন লেনদেনের প্রয়োজন। তবে, যেহেতু আমি চালিত সিস্টেম পরীক্ষার সময় এটি বারবার ঘটে (যার গাজিলিয়ন ট্রানজেকশন রয়েছে) আমি সন্দেহ করি যে এর একটি নির্দিষ্ট কারণ রয়েছে।
daniel_or_else

কোনও পরিবর্তন নেই এমন সারিগুলি আপডেট করার চেষ্টা করার সময় আমি এই সমস্যার মুখোমুখি হয়েছি । কোনও পার্থক্য না থাকলে কিছু আপডেট করবেন না।
ফিফটিম্যান

উত্তর:


62

আপনার লেনদেনের জন্য কোড এবং ম্যাপিং ব্যতীত সমস্যাটি তদন্ত করা অসম্ভবের পাশে।

তবে কী কারণে সমস্যাটি হয় তার একটি আরও ভাল হ্যান্ডেল পেতে নিম্নলিখিত ব্যবহারের চেষ্টা করুন:

  • আপনার হাইবারনেট কনফিগারেশনে হাইবারনেট.শো_এসকিএলকে সত্য হিসাবে সেট করুন। এটি আপনাকে কার্যকর করা এবং এটির জন্য SQL প্রদর্শন করবে।
  • স্প্রিং এবং হাইবারনেটের জন্য লগ স্তরগুলি ডিবিবিউতে সেট করুন, আবার এটি আপনাকে আরও ভাল ধারণা দেবে যে কোন লাইনে সমস্যার কারণ রয়েছে।
  • একটি ইউনিট পরীক্ষা তৈরি করুন যা বসন্তে কোনও লেনদেন পরিচালককে কনফিগার না করেই সমস্যার প্রতিস্থাপন করে। এটি আপনাকে কোডের আপত্তিকর লাইন সম্পর্কে আরও ভাল ধারণা দেয়।

আশা করি এইটি কাজ করবে.


21
হাইবারনেট.শো_সকিউএল> আমি বরং লগ বিভাগটি org.hibernate.SQL স্তরটি DEBUG এ সেট করার পরামর্শ দিচ্ছি। এইভাবে আপনাকে কেবল লগিংয়ের জন্য হাইবারনেট কনফিগারেশনটি সংশোধন করার দরকার নেই।
থিয়েরি

"Show_sql" এর ব্যবহার খুব ভার্জোজ এবং প্রযোজনায় অনুশীলনযোগ্য হতে পারে। এর জন্য আমি PS.toString () দিয়ে বিবৃতিটি মুদ্রণ করতে ব্যাচিংবাচার শ্রেণির 74 নং লাইনে ক্যাচ ক্লজটি সংশোধন করেছি যাতে সমস্যা আছে কেবলমাত্র বিবৃতিটি থাকতে হবে।
অর্ডেন

71

আইডি দ্বারা কোনও রেকর্ড মুছে ফেলার সময় আমি একই ব্যতিক্রম পেয়েছি যা একেবারেই নেই। সুতরাং আপনি যে রেকর্ডটি আপডেট করছেন / ডিলিট করছেন তা ডিবিতে বিদ্যমান রয়েছে কিনা তা পরীক্ষা করুন


12
আমার যখন এই সমস্যাটি হয়েছিল তখন আমি একটি শিশুকে পিতামাতার সাথে সম্পর্ক থেকে সরিয়ে দিয়ে, পিতামাতাকে সংরক্ষণ করি (যা শিশুটিকে মুছে দেয়) এবং তারপরে ম্যানুয়ালি শিশুটিকে মোছার চেষ্টাও করেছি।
ডেভ থিবেন

এটি আমার সমস্যার সমাধান করেছে। রেকর্ডটির অস্তিত্ব ছিল না এবং আমার সার্ভিসটি আপডেটআল () পদ্ধতিতে কল করছিল যখন এটির জন্য আসলে তৈরিরআরআপটেলএল () পদ্ধতিটি কল করা দরকার। ধন্যবাদ।
মিতল প্রীতমণি

3
তাহলে কীভাবে বিষয়টি সমাধান করবেন? যদি আমি একটি রেকর্ড পাই, এবং তারপরে এটি মুছুন; তবে অন্যটি মুছে ফেলার আগে যদি সিস্টেম ইতিমধ্যে এটি মুছে ফেলে তবে আমার অ্যাপ্লিকেশনটি ব্যতিক্রম ছুঁড়ে দেবে।
স্টনি

@ ডেভিয়েটিবেন, এটি আমার প্রয়োজনীয় তথ্য ছিল। আমি বুঝতে পারি না যে পিতামাতার সাথে সম্পর্ক মুছে ফেলার ক্ষেত্রে অবিচল।
তুষারপাত

সলিউডটি লক করার জন্য রেকর্ড আনার সময় সমাধানটি আপডেটের জন্য নির্বাচন ব্যবহার করা হয়, সুতরাং আপনার করার আগে আর কিছুই মুছতে পারে না।
ম্যাথু

55

সমাধান: আইডি সম্পত্তির জন্য হাইবারনেট ম্যাপিং ফাইলে আপনি যদি কোনও জেনারেটর শ্রেণি ব্যবহার করেন তবে সেই সম্পত্তির জন্য আপনাকে সেটার পদ্ধতি ব্যবহার করে স্পষ্ট করে মান নির্ধারণ করা উচিত নয়।

আপনি যদি আইডির বৈশিষ্ট্যের মানটি স্পষ্টভাবে সেট করেন তবে এটি উপরের ত্রুটির দিকে পরিচালিত করবে। এই ত্রুটি এড়াতে এটি পরীক্ষা করুন। অথবা আপনি যখন ম্যাপিং ফাইলটিতে ক্ষেত্রের জেনারেটর = "নেটিভ" বা "ইনক্রিমেন্টাল" উল্লেখ করেন এবং এটির ত্রুটি দেখাতে থাকে তবে আপনার ডেটাবেসে টেবিলটি ম্যাপ করা টেবিলটি অটো_সংশোধিত সমাধান নয়: আপনার ডেটাবেসে যান এবং অটো_সংশোধন সেট করতে আপনার টেবিলটি আপডেট করুন


2
পুরোপুরি সঠিক. এটি অবশ্যই সঠিক উত্তর হবে। ধন্যবাদ @ রদা বিরামণে
কুলদীপ ভার্মা

1
তবে , আপনি ID মানটি '0' এ সেট করতে পারেন এবং তারপরে হাইবারনেট এটিকে ওভাররাইট করতে নির্দ্বিধায় অনুভব করবে
forresthopkinsa

1
ধন্যবাদ! কেন এটি সর্বোচ্চ র‌্যাঙ্কের উত্তর নয় তা নিশ্চিত নন।
স্টুয়ার্ট ম্যাকআইন্টির

18

দুর্ঘটনাক্রমে একবার আমার সাথে এটি ঘটেছিল যখন আমি কিছু বস্তুর (পরীক্ষার) নির্দিষ্ট আইডি নিযুক্ত করছিলাম এবং তারপরে আমি সেগুলি ডাটাবেসে সংরক্ষণ করার চেষ্টা করছিলাম। সমস্যাটি হ'ল ডাটাবেসটিতে অবজেক্টগুলির আইডি স্থাপনের জন্য একটি নির্দিষ্ট নীতি ছিল। হাইবারনেট স্তরে যদি আপনার নীতি থাকে তবে কেবল একটি আইডি বরাদ্দ করবেন না


15

আমার ক্ষেত্রে, আমি অনুরূপ দুটি ক্ষেত্রে এই ব্যতিক্রমটিতে এসেছি:

  • বর্ণিত একটি পদ্ধতিতে @Transactionalআমার অন্য একটি পরিষেবাতে কল হয়েছিল (দীর্ঘ সময় সাড়া দিয়ে)। পদ্ধতিটি সত্তার কিছু বৈশিষ্ট্য আপডেট করে (পদ্ধতির পরে, সত্তাটি ডাটাবেসে এখনও বিদ্যমান)। ব্যবহারকারীর দ্বিতীয়বার ট্রানজেকশনাল পদ্ধতি থেকে প্রস্থান করার সময় যদি পদ্ধতিটি দুইবার (যেমন তিনি মনে করেন এটি প্রথমবারের মতো কাজ করে না) অনুরোধ করে তবে হাইবারনেট কোনও সত্তাকে আপডেট করার চেষ্টা করে যা ইতিমধ্যে লেনদেনের শুরু থেকেই তার অবস্থার পরিবর্তন করেছে। হাইবারনেট কোনও রাজ্যে কোনও সত্তার সন্ধান করার জন্য এবং একই সত্তাটি খুঁজে পেয়েছে তবে ইতিমধ্যে প্রথম অনুরোধে পরিবর্তিত হয়েছে, এটি সত্তাকে আপডেট করতে পারে না বলে এটি ব্যতিক্রম ছুঁড়ে ফেলে। এটি জিআইটির দ্বন্দ্বের মতো।
  • আমার কাছে স্বয়ংক্রিয় অনুরোধ ছিল (প্ল্যাটফর্ম পর্যবেক্ষণের জন্য) যা কোনও সত্তা আপডেট করে (এবং কয়েক সেকেন্ড পরে ম্যানুয়াল রোলব্যাক)। তবে এই প্ল্যাটফর্মটি ইতিমধ্যে একটি পরীক্ষা দল ব্যবহার করেছে। যখন কোনও পরীক্ষক স্বয়ংক্রিয় অনুরোধগুলির মতো একই সত্তায় একটি পরীক্ষা করেন, (মিলিসেকেন্ডের একই শতকের মধ্যে), আমি ব্যতিক্রম পাই। পূর্ববর্তী ক্ষেত্রে হিসাবে, দ্বিতীয় লেনদেন থেকে প্রস্থান করার সময়, পূর্বে প্রাপ্ত সত্তা ইতিমধ্যে পরিবর্তিত হয়েছিল।

উপসংহার: আমার ক্ষেত্রে এটি কোনও সমস্যা ছিল না যা কোডটিতে পাওয়া যাবে। এই ব্যতিক্রমটি ছুঁড়ে ফেলা হয় যখন হাইবারনেট সন্ধান করেছে যে বর্তমান লেনদেনের সময় ডাটাবেস থেকে সত্তাটি প্রথম পাওয়া গেছে , তাই এটি ডাটাবেসে ফ্লাশ করতে পারে না কারণ হাইবারনেট জানে না যে সত্তার সঠিক সংস্করণ: এটির বর্তমান শুরুতে লেনদেন আনুন; বা ইতিমধ্যে ডাটাবেসে সঞ্চিত একটি।

সমাধান: সমস্যাটি সমাধান করার জন্য আপনাকে হাইবারনেট লকমোডের সাথে খেলতে হবে যা আপনার প্রয়োজনীয়তার সাথে সবচেয়ে উপযুক্ত।


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

1
আমার বেশিরভাগ সময় সমস্যা ছিল এবং আমি ঠিক যে সমাধানটি রেখেছি তা ভালভাবে মনে নেই, তবে এটি ছিল LockMode.READবা ছিল LockMode.OPTIMISTIC
সেরজিও লেমা

13

আমি এই সমস্যার মুখোমুখি হয়েছি এবং জানতে পেরেছিলাম যে আমি একটি রেকর্ড মুছে ফেলছি এবং পরে হাইবারনেট লেনদেনে এটি আপডেট করার চেষ্টা করছি।


9

এটি ঘটতে পারে যখন ট্রিগার (গুলি) অতিরিক্ত ডিএমএল (ডেটা পরিবর্তন) অনুসন্ধানগুলি কার্যকর করে যা সারি গণনাগুলিকে প্রভাবিত করে। আমার সমাধানটি ছিল আমার ট্রিগারটির শীর্ষে নিম্নলিখিতগুলি যুক্ত করা:

SET NOCOUNT ON;

1
এই উত্তরটি আমাকে সঠিক দিকে পাঠিয়েছে। আমি একটি উত্তরাধিকারের ডাটাবেসের সাথে কাজ করছিলাম যার এতে একটি ট্রিগার ছিল - ভাগ্যক্রমে আমি ট্রিগারটি কোড দিয়ে যা করেছে তা প্রতিস্থাপন করছি, তাই আমি কেবল এটি মুছতে পারি।
এস ব্যাগি

2
+1 এটি আমার সমস্যাও ছিল। আমি পোস্টগ্রেসকিএল ব্যবহার করছিলাম, সুতরাং সারি গণনা পরীক্ষা বন্ধ করার জন্য @ এসকিউএলএনট্রি টীকাটি ব্যবহার করা দরকার: প্রযুক্তি-
ebay.de/the-teams/mobile-de/blog/…

নোট অফ অফ *
জি সিয়ার্ডিনি

7

আমি একই সমস্যা ছিল। কোডটি পরীক্ষার পরিবেশে কাজ করছিল। কিন্তু এটি মঞ্চ পরিবেশে কাজ করে না।

org.hibernate.jdbc.BatchedTooManyRowsAffectedException: Batch update returned unexpected row count from update [0]; actual row count: 3; expected: 1

সমস্যাটি ছিল ডিবি টেবিলটি পরীক্ষায় প্রতিটি প্রাথমিক কীটির জন্য টেবিলটির একক প্রবেশ ছিল। কিন্তু ডিবি মঞ্চে একই প্রাথমিক কীটির জন্য একাধিক এন্ট্রি ছিল। (ডিবি মঞ্চায়নের সমস্যাটি রয়েছে টেবিলে কোনও প্রাথমিক কী বাধাও ছিল না একাধিক প্রবেশও ছিল))

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

আমি মুছে ফেলা প্রাথমিক কী এবং প্রাথমিক কী সীমাবদ্ধতা যুক্ত করেছে এমন সমস্ত রেকর্ড সরিয়ে দেওয়ার পরে। এটা ঠিক কাজ করছে।

Hibernate - Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1

আসল সারি গণনা: 0 // এর অর্থ আপডেট
আপডেট করার জন্য কোনও রেকর্ড পাওয়া যায় নি : 0 // মানে কোনও রেকর্ড পাওয়া যায়নি তাই আপডেটের
প্রত্যাশিত কিছুই নেই : 1 // মানে ডিবি টেবিলের কী সহ কমপক্ষে 1 রেকর্ড প্রত্যাশিত।

এখানে সমস্যাটি হ'ল ক্যোয়ারী কিছু কীটির জন্য একটি রেকর্ড আপডেট করার চেষ্টা করছে তবে হাইবারনেট কীটির সাথে কোনও রেকর্ড খুঁজে পায় নি।


হাই @ পারাগফ্লিউম, আমি একই ত্রুটি পেয়েছি "ব্যাচ আপডেট আপডেট থেকে অপ্রত্যাশিত সারি গণনা ফিরিয়েছে: 0 প্রকৃত সারি গণনা: 0 প্রত্যাশিত: 1" যখন আমি আমার ডেটাবেস থেকে একটি অবজেক্ট নির্বাচন করার চেষ্টা করি তখনই কেবল কোনও উত্পাদন বিদ্যমান, আপনার কি কোনও সমস্যা আছে? এই সমস্যাটি কীভাবে সমাধান করবেন সে সম্পর্কে ধারণা, আমি একটি জটিল পরিস্থিতিতে আছি। শুভেচ্ছা!
জেমস

আমি মনে করি ক্যোরিটি ডিবিতে কোনও রেকর্ড খুঁজে পায়নি, এটি ডিবিতে একটি রেকর্ড খুঁজে পাওয়ার প্রত্যাশা করছে, যা এটি আপডেট করার চেষ্টা করছে। রেকর্ডটি আসলে ডিবিতে উপস্থিত থাকলে আপনি ম্যানুয়ালি / ক্যোয়ারী-ব্রাউজারটি পরীক্ষা করতে পারেন।
প্যারাগফ্লুম

হ্যাঁ রেকর্ডটি বিদ্যমান, তবে আমার সমস্যা হায়বারনেট আপডেট করার চেষ্টা করছে কেন, আমি কেবলমাত্র একটি নির্বাচিত পরিষেবা ব্যবহার করছি ডাটাবেস থেকে অবজেক্টটি পেতে!
জেমস

হতে পারে আপনি বস্তুর অবস্থা পরিবর্তন করার চেষ্টা করছেন। এবং সেশন এখনও খোলা আছে।
প্যারাগফ্লুম

আমি কীভাবে এই আচরণটি পরীক্ষা করতে পারি, কারণ আমি সেই ব্যক্তি নই যা পরিষেবাটি বিকশিত করে ...
জেমস

5

জুলিয়াস যেমন বলেছিলেন তখন এমনটি ঘটে যখন কোনও আপডেটে এমন কোনও অবজেক্ট আসে যার সাথে তার শিশুদের মুছে ফেলা হয়। (সম্ভবত পুরো পিতা অবজেক্টের জন্য একটি আপডেটের প্রয়োজন ছিল এবং কখনও কখনও আমরা বাচ্চাদের মুছে ফেলা এবং বাবার যে কোনও আপডেটে বাবার যে আপডেট থাকতে পারে তার সাথে তাদের পুনরায় সন্নিবেশ করানো পছন্দ করি (নতুন, পুরাতন কিছু যায় আসে না) এর অন্যান্য সরল ক্ষেত্রগুলি) সুতরাং ... এই কাজের জন্য বাচ্চাদের মুছে ফেলতে (একটি লেনদেনের মধ্যে) কল করে childrenList.clear()(বাচ্চাদের মধ্য দিয়ে লুপ করবেন না এবং প্রতিটিকে কিছু দিয়ে মুছে দিন childDAO.delete(childrenList.get(i).delete()))এবং সেটিং করুন @OneToMany(cascade = CascadeType.XXX ,orphanRemoval=true)ফাদার অবজেক্টের সাইডে। তারপরে বাবাকে আপডেট করুন (fatherDAO.update (father))। (প্রতিটি পিতার আপত্তিটির জন্য পুনরাবৃত্তি করুন) ফলস্বরূপ যে বাচ্চাদের তাদের পিতার সাথে তাদের লিঙ্ক ছিন্ন হয়ে যায় এবং তারপরে ফ্রেমওয়ার্কের মাধ্যমে তাদের এতিম হিসাবে সরানো হয়।


5

আমরা এই সমস্যার মুখোমুখি হয়েছি যেখানে আমাদের একাধিক সম্পর্ক ছিল।

হাইবারনেট এইচবিএম ম্যাপিং ফাইলের জন্য মাস্টারের জন্য সেট টাইপের ব্যবস্থা সহ বস্তুর জন্য যুক্ত করা হয়েছে cascade="save-update"এবং এটি দুর্দান্ত কাজ করেছে।

এটি ছাড়াই, ডিফল্টরূপে হাইবারনেট অস্তিত্বহীন রেকর্ডের জন্য আপডেট করার চেষ্টা করে এবং এর পরিবর্তে এটি সন্নিবেশ করে।


4

আপনি যখন UPDATEকোনও প্রাথমিক কী চেষ্টা করেন তখন এটিও ঘটতে পারে ।


3

আমি একই সমস্যা পেয়েছি এবং আমি যাচাই করেছি যা অটো ইনক্রিমেন্ট প্রাথমিক কী এর কারণে ঘটতে পারে। এই সমস্যাটি সমাধান করতে ডেটা সেট সহ অটো ইনক্রিমেন্ট ভ্যালু ইনসেট করবেন না। প্রাথমিক কী ছাড়াই ডেটা .োকান।


3

এই ত্রুটিটি পাওয়ার অন্য একটি উপায় হ'ল যদি আপনার কোনও সংগ্রহের নਾਲ আইটেম থাকে।


2

এটি ঘটে যখন আপনি একই অবজেক্টটি মুছতে চেষ্টা করেন এবং আবার একই বস্তুটিকে আপডেট করার পরে মুছার পরে এটি ব্যবহার করুন

session.clear ();


2

এটি আমার সাথেও ঘটেছিল, কারণ আমার লং হিসাবে আমার আইডি ছিল, এবং আমি 0 টির মানটি পেয়েছিলাম, এবং যখন আমি ডাটাবেসে সংরক্ষণ করার চেষ্টা করেছি তখন আমি এই ত্রুটিটি পেয়েছি, তখন আমি আইডি সেটটি বাতিল করে স্থির করেছিলাম।


1

আমি নিজে যখন এ্যানুয়ালিটেড পদ্ধতিতে ম্যানুয়ালি আরম্ভ করে এবং লেনদেন করার সময় এই সমস্যাটি নিয়ে এসেছিলাম @Transactional। সক্রিয় লেনদেন ইতিমধ্যে বিদ্যমান কিনা তা সনাক্ত করে আমি সমস্যাটি সমাধান করেছি।

//Detect underlying transaction
if (session.getTransaction() != null && session.getTransaction().isActive()) {
    myTransaction = session.getTransaction();
    preExistingTransaction = true;
} else {
    myTransaction = session.beginTransaction();
}

তারপরে আমি স্প্রিংকে লেনদেনের প্রতিশ্রুতি সামলানোর অনুমতি দিয়েছিলাম।

private void finishTransaction() {
    if (!preExistingTransaction) {
        try {
            tx.commit();
        } catch (HibernateException he) {
            if (tx != null) {
                tx.rollback();
            }
            log.error(he);
        } finally {
            if (newSessionOpened) {
                SessionFactoryUtils.closeSession(session);
                newSessionOpened = false;
                maxResults = 0;
            }
        }
    }
}

1

আপনি যখন জেএসএফ পরিচালিত বিনকে ঘোষণা করেছিলেন এটি হ'ল

@RequestScoped;

যখন আপনি হিসাবে ঘোষণা করা উচিত

@SessionScoped;

শুভেচ্ছা সহ;


1

আমি এই ত্রুটিটি পেয়েছি যখন আমি কোনও আইডি দিয়ে কোনও অবজেক্ট আপডেট করার চেষ্টা করেছি যা ডাটাবেসে উপস্থিত নেই। আমার ভুলের কারণটি হ'ল আমি নিজেই আইডিটির নামের সাথে সম্পত্তিটি ক্লায়েন্টের পাশের JSON- উপস্থাপনের উদ্দেশ্যে অর্পণ করেছিলাম এবং তারপরে সার্ভারের দিকে অবজেক্টটি deserialize করার সময় এই 'id' বৈশিষ্ট্যটি দৃষ্টান্ত পরিবর্তনশীলকে ওভাররাইট করে ( 'আইডি' নামেও ডাকা হয়) যা হাইবারনেট তৈরি করার কথা ছিল। সুতরাং আপনি যদি সনাক্তকারী তৈরি করতে হাইবারনেট ব্যবহার করছেন তবে সংঘর্ষের নামকরণের বিষয়ে সতর্ক হন।


1

আমিও একই চ্যালেঞ্জ পেরিয়ে এসেছি। আমার ক্ষেত্রে আমি এমন একটি অবজেক্ট আপডেট করছি যা ব্যবহার করেও বিদ্যমান ছিল না hibernateTemplate

আসলে আমার আবেদনে আমি আপডেট করার জন্য একটি ডিবি অবজেক্ট পেয়েছিলাম। এবং এর মানগুলি আপডেট করার সময়, আমি ভুলভাবে এটির আইডিও আপডেট করেছিলাম এবং এটি আপডেট করতে এগিয়ে গিয়েছিলাম এবং উল্লিখিত ত্রুটিটি পেরিয়ে এসেছি।

আমি hibernateTemplateসিআরইউডি অপারেশনের জন্য ব্যবহার করছি ।


1

সমস্ত উত্তর পড়ার পরে হাইবারনেটের বিপরীত পরিমাণ সম্পর্কে কথা বলতে কাউকে খুঁজে পেল না।

আমার মতে আপনার বিপরীত কী শব্দটি প্রশংসনীয়ভাবে সেট করা আছে কিনা তা আপনার সম্পর্কের ম্যাপিংয়ে যাচাই করা উচিত । বিপরীত কীওয়ার্ডটি সম্পর্ক বজায় রাখার জন্য কোন পক্ষের মালিক তা নির্ধারণ করতে তৈরি করা হয়। আপডেট এবং সন্নিবেশকরণের পদ্ধতিটি এই বৈশিষ্ট্যের সাথে সিসিপিডিংয়ের পরিবর্তিত হয়।

ধরা যাক আমাদের দুটি টেবিল রয়েছে:

প্রিন্সিপাল টেবিল , মিডল_ টেবিল

অনেকের সাথে একটি সম্পর্কের সাথে । হাইবারেন্টেট ম্যাপিং ক্লাসগুলি যথাক্রমে অধ্যক্ষ এবং মধ্য

তাই প্রিন্সিপাল ক্লাসের মাঝারি বিষয়গুলির একটি এসইটি রয়েছে । এক্সএমএল ম্যাপিং ফাইলটি নিম্নলিখিতগুলির মতো হওয়া উচিত:

<hibernate-mapping>
    <class name="path.to.class.Principal" table="principal_table" ...>
    ...
    <set name="middleObjects" table="middle_table" inverse="true" fetch="select">
        <key>
            <column name="PRINCIPAL_ID" not-null="true" />
        </key>
        <one-to-many class="path.to.class.Middel" />
    </set>
    ...

বিপরীতটি "সত্য" এ সেট করা আছে, এর অর্থ "মধ্যম" শ্রেণি সম্পর্কের মালিক, সুতরাং অধ্যক্ষ শ্রেণি সম্পর্কের আপডেট করবে না

সুতরাং আপডেট করার পদ্ধতিটি এভাবে প্রয়োগ করা যেতে পারে:

session.beginTransaction();

Principal principal = new Principal();
principal.setSomething("1");
principal.setSomethingElse("2");


Middle middleObject = new Middle();
middleObject.setSomething("1");

middleObject.setPrincipal(principal);
principal.getMiddleObjects().add(middleObject);

session.saveOrUpdate(principal);
session.saveOrUpdate(middleObject); // NOTICE: you will need to save it manually

session.getTransaction().commit();

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


1

আমাদের ক্ষেত্রে আমরা অবশেষে স্ট্যালস্টেটএক্সেপশন এর মূল কারণটি খুঁজে পেয়েছি।

প্রকৃতপক্ষে আমরা একক হাইবারনেট সেশনে দু'বার সারি মুছে ফেলছিলাম। আগে আমরা ojdbc6 lib ব্যবহার করতাম, এবং এই সংস্করণে এটি ঠিক ছিল।

কিন্তু যখন আমরা odjc7 বা ojdbc8 এ আপগ্রেড করেছি, দুবার রেকর্ড মুছে ফেলা ব্যতিক্রম ছুঁড়েছিল। আমাদের কোডটিতে বাগ ছিল যেখানে আমরা দুবার মুছে ফেলছিলাম, কিন্তু ওজডবিসি 6 তে এটি স্পষ্ট ছিল না।

আমরা কোডের এই অংশটি দিয়ে পুনরুত্পাদন করতে সক্ষম হয়েছি:

Detail detail = getDetail(Long.valueOf(1396451));
session.delete(detail);
session.flush();
session.delete(detail);
session.flush();

প্রথমে ফ্লাশ হাইবারনেট যায় এবং ডাটাবেসে পরিবর্তন করে। ২ য় ফ্লাশ চলাকালীন হাইবারনেট সেশনটির বস্তুকে প্রকৃত টেবিলের রেকর্ডের সাথে তুলনা করে, তবে একটিটি খুঁজে পেল না, তাই ব্যতিক্রম।


1

এই সমস্যাটি মূলত তখন ঘটে যখন আমরা কোনও চলমান সেশনের মাধ্যমে মেমরিতে ইতিমধ্যে আনীত বস্তুটি সংরক্ষণ বা আপডেট করার চেষ্টা করছি are আপনি যদি সেশন থেকে অবজেক্টটি এনেছেন এবং আপনি ডাটাবেসে আপডেট করার চেষ্টা করছেন, তবে এই ব্যতিক্রমটি ছুঁড়ে দেওয়া যেতে পারে।

আমি সেশন ব্যবহার করেছি ev হাইবারনেটে সঞ্চিত ক্যাশেটি প্রথমে সরাতে বা আপনি যদি ডেটা হারানোর ঝুঁকি নিতে না চান, তবে ডেটা টেম্প স্টোর করার জন্য আপনি অন্য কোনও জিনিস তৈরি করতে পারেন।

     try
    {
        if(!session.isOpen())
        {
            session=EmployeyDao.getSessionFactory().openSession();
        }
            tx=session.beginTransaction();

        session.evict(e);
        session.saveOrUpdate(e);
        tx.commit();;
        EmployeyDao.shutDown(session);
    }
    catch(HibernateException exc)
    {
        exc.printStackTrace();
        tx.rollback();
    }

1

হাইবারনেট 5.4.1 এবং এইচএইচএইচ -12878 ইস্যু

হাইবারনেট 5.4.1 এর আগে, আশাবাদী লকিং ব্যর্থতার ব্যতিক্রম (যেমন, StaleStateExceptionবাOptimisticLockException ) ব্যর্থতার বিবৃতিটি অন্তর্ভুক্ত করেনি।

HHH-12878 ইস্যু হাইবারনেট উন্নত করতে তৈরি করা হয়েছে যাতে একটি আশাবাদী লকিং ব্যতিক্রম নিক্ষেপ, JDBC এর PreparedStatementবাস্তবায়ন পাশাপাশি লগ করা হয়:

if ( expectedRowCount > rowCount ) {
    throw new StaleStateException(
            "Batch update returned unexpected row count from update ["
                    + batchPosition + "]; actual row count: " + rowCount
                    + "; expected: " + expectedRowCount + "; statement executed: "
                    + statement
    );
}

পরীক্ষার সময়

BatchingOptimisticLockingTestনতুন আচরণটি কীভাবে কাজ করে তা প্রদর্শনের জন্য আমি আমার উচ্চ-পারফরম্যান্স জাভা পার্সিনিস্টিশন গিটহাবের সংগ্রহশালা তৈরি করেছি।

প্রথমত, আমরা এমন একটি Postসত্তাকে সংজ্ঞায়িত করব যা কোনও @Versionসম্পত্তিকে সংজ্ঞায়িত করে , সুতরাং অন্তর্নিহিত আশাবাদী লকিং প্রক্রিয়াটিকে সক্ষম করে :

@Entity(name = "Post")
@Table(name = "post")
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    private String title;

    @Version
    private short version;

    public Long getId() {
        return id;
    }

    public Post setId(Long id) {
        this.id = id;
        return this;
    }

    public String getTitle() {
        return title;
    }

    public Post setTitle(String title) {
        this.title = title;
        return this;
    }

    public short getVersion() {
        return version;
    }
}

নিম্নলিখিত 3 কনফিগারেশন বৈশিষ্ট্যগুলি ব্যবহার করে আমরা জেডিবিসি ব্যাচিং সক্ষম করব:

properties.put("hibernate.jdbc.batch_size", "5");
properties.put("hibernate.order_inserts", "true");
properties.put("hibernate.order_updates", "true");

আমরা 3 টি Postসত্তা তৈরি করতে যাচ্ছি :

doInJPA(entityManager -> {
    for (int i = 1; i <= 3; i++) {
        entityManager.persist(
            new Post()
                .setTitle(String.format("Post no. %d", i))
        );
    }
});

এবং হাইবারনেট একটি জেডিবিসি ব্যাচের সন্নিবেশ সম্পাদন করবে:

SELECT nextval ('hibernate_sequence')
SELECT nextval ('hibernate_sequence')
SELECT nextval ('hibernate_sequence')

Query: [
    INSERT INTO post (title, version, id) 
    VALUES (?, ?, ?)
], 
Params:[
    (Post no. 1, 0, 1), 
    (Post no. 2, 0, 2), 
    (Post no. 3, 0, 3)
]

সুতরাং, আমরা জানি যে জেডিবিসি ব্যাচিং ঠিক কাজ করে।

এখন, আশাবাদী লকিংয়ের প্রতিলিপি তৈরি করা যাক:

doInJPA(entityManager -> {
    List<Post> posts = entityManager.createQuery("""
        select p 
        from Post p
        """, Post.class)
    .getResultList();

    posts.forEach(
        post -> post.setTitle(
            post.getTitle() + " - 2nd edition"
        )
    );

    executeSync(
        () -> doInJPA(_entityManager -> {
            Post post = _entityManager.createQuery("""
                select p 
                from Post p
                order by p.id
                """, Post.class)
            .setMaxResults(1)
            .getSingleResult();

            post.setTitle(post.getTitle() + " - corrected");
        })
    );
});

প্রথম লেনদেন সমস্ত Postসত্ত্বাকে নির্বাচন করে এবং সংশোধন করেtitle বৈশিষ্ট্যগুলিকে ।

যাইহোক, প্রথমটি EntityManagerফ্লাশ করার আগে আমরা executeSyncপদ্ধতিটি ব্যবহার করে একটি দ্বিতীয় ট্রানজিশন চালিয়ে যাচ্ছি ।

দ্বিতীয় লেনদেন প্রথমটি সংশোধন করে Post, তাই এটি versionবাড়ানো হবে:

Query:[
    UPDATE 
        post 
    SET 
        title = ?, 
        version = ? 
    WHERE 
        id = ? AND 
        version = ?
], 
Params:[
    ('Post no. 1 - corrected', 1, 1, 0)
]

এখন, যখন প্রথম লেনদেনটি ফ্ল্যাশ করার চেষ্টা করে EntityManager, আমরা তা পেয়ে যাব OptimisticLockException:

Query:[
    UPDATE 
        post 
    SET 
        title = ?, 
        version = ? 
    WHERE 
        id = ? AND 
        version = ?
], 
Params:[
    ('Post no. 1 - 2nd edition', 1, 1, 0), 
    ('Post no. 2 - 2nd edition', 1, 2, 0), 
    ('Post no. 3 - 2nd edition', 1, 3, 0)
]

o.h.e.j.b.i.AbstractBatchImpl - HHH000010: On release of batch it still contained JDBC statements

o.h.e.j.b.i.BatchingBatch - HHH000315: Exception executing batch [
    org.hibernate.StaleStateException: 
    Batch update returned unexpected row count from update [0]; 
    actual row count: 0; 
    expected: 1; 
    statement executed: 
        PgPreparedStatement [
            update post set title='Post no. 3 - 2nd edition', version=1 where id=3 and version=0
        ]
], 
SQL: update post set title=?, version=? where id=? and version=?

সুতরাং, আপনাকে এই উন্নতি থেকে উপকার পেতে হাইবারনেট 5.4.1 বা আরও উন্নত করতে হবে।


0

আপনি যদি দেশীয় এসকিএল কোয়েরি ব্যবহার করে ডেটা সেটে কিছু পরিবর্তন করেন তবে একই ডেটা সেটের জন্য অবিচলিত অবজেক্ট সেশন ক্যাশে উপস্থিত থাকলে এটি ঘটেছিল। সেশন.এভিক্ট (আপনারঅজেক্ট) ব্যবহার করুন;


0

হাইবারনেট অধিবেশন থেকে বস্তুগুলি ক্যাশে করে। যদি 1 টিরও বেশি ব্যবহারকারীর মাধ্যমে অবজেক্ট অ্যাক্সেস এবং সংশোধিত হয় তবে org.hibernate.StaleStateExceptionনিক্ষেপ করা হতে পারে। এটি লক সংরক্ষণ বা ব্যবহারের আগে একীকরণ পদ্ধতি / রিফ্রেশ সত্তা পদ্ধতিতে সমাধান করা যেতে পারে। আরও তথ্য: http://java-fp.blogspot.lt/2011/09/orghiberniestalestateexception-batch.html


0

অন্যতম একটি ঘটনা

SessionFactory sf=new Configuration().configure().buildSessionFactory();
Session session=sf.openSession();

UserDetails user=new UserDetails();

session.beginTransaction();
user.setUserName("update user agian");
user.setUserId(12);
session.saveOrUpdate(user);
session.getTransaction().commit();
System.out.println("user::"+user.getUserName());

sf.close();

0

আমি এই ব্যতিক্রমটির মুখোমুখি ছিলাম, এবং হাইবারনেট ভালভাবে কাজ করছিল। আমি pgAdmin ব্যবহার করে ম্যানুয়ালি একটি রেকর্ড inোকানোর চেষ্টা করেছি, এখানে বিষয়টি স্পষ্ট হয়ে উঠেছে। এসকিউএল সন্নিবেশ জিজ্ঞাসা 0 টি সন্নিবেশ দেয়। এবং একটি ট্রিগার ফাংশন রয়েছে যা এই সমস্যার কারণ এটি শূন্য ফিরে আসে। সুতরাং আমি এটি নতুন ফিরে সেট করতে হবে। এবং অবশেষে আমি সমস্যার সমাধান করেছি।

আশা যে কোনও শরীরকে সাহায্য করে।


0

আমি এই ত্রুটিটি পেয়েছি কারণ আমি ভুল করে IDকলামটি ব্যবহার করে ম্যাপ করেছিId(x => x.Id, "id").GeneratedBy.**Assigned**();

সমস্যাটি সমাধান করে সমাধান করে Id(x => x.Id, "id").GeneratedBy.**Identity**();



0

আমার ক্ষেত্রে ডেটাবেস নিয়ে একটি সমস্যা ছিল কারণ স্টোরড প্রোকগুলির মধ্যে একটিতে সমস্ত সিপিইউ উচ্চ ডিবি প্রতিক্রিয়া বারের কারণে গ্রাস করে। এটি খুন হয়ে গেলে বিষয়টি সমাধান হয়ে যায়।

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