"অটো" কৌশলটি ব্যবহার করার সময় ডক্ট্রিনের সাথে আইডি স্পষ্টভাবে সেট করুন


101

আমার সত্তা এই আইডিটির জন্য এই টিকাটি ব্যবহার করে:

/**
 * @orm:Id
 * @orm:Column(type="integer")
 * @orm:GeneratedValue(strategy="AUTO")
 */
protected $id;

একটি পরিষ্কার ডাটাবেস থেকে, আমি একটি পুরানো ডাটাবেস থেকে বিদ্যমান রেকর্ড আমদানি করছি এবং একই আইডি রাখার চেষ্টা করছি। তারপরে, নতুন রেকর্ড যুক্ত করার সময়, আমি মাইএসকিউএলকে যথারীতি আইডি কলামটি স্বয়ংক্রিয়ভাবে বাড়িয়ে তুলতে চাই।

দুর্ভাগ্যক্রমে, এটি প্রদর্শিত হয় Doctrine2 সম্পূর্ণরূপে নির্দিষ্ট আইডি উপেক্ষা করে।


নতুন সমাধান

নীচে সুপারিশ অনুযায়ী, নিম্নলিখিত পছন্দসই সমাধান:

$this->em->persist($entity);

$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);
$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());

ওল্ড সলিউশন

কারণ জেনারেটর কৌশল নির্ধারণের জন্য মতবাদ ক্লাসমেটাডাটা থেকে দূরে রয়েছে, সত্তা ম্যানেজারে সত্তাটি পরিচালনা করার পরে এটি সংশোধন করতে হবে:

$this->em->persist($entity);

$metadata = $this->em->getClassMetaData(get_class($entity));
$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);

$this->em->flush();

আমি এটি এখনই মাইএসকিউএলে পরীক্ষা করেছি এবং এটি প্রত্যাশার মতো কাজ করেছে, যার অর্থ একটি কাস্টম আইডি সহ সত্তা সেই আইডি সহ সঞ্চিত ছিল, যখন একটি আইডিবিহীন তারা ব্যবহার করত lastGeneratedId() + 1


আপনি কি বিদ্যমান রেকর্ড আমদানি করতে মতবাদ ব্যবহার করছেন?
রোজোকা

4
এরিক, কোন বিষয় নয় ... আপনি যা করতে চেষ্টা করছেন তা আমি দেখতে পাচ্ছি। আপনার মূলত আপনার একটি @ জেনারেটেড ভ্যালু (কৌশল = "এটি নির্ভর করে") দরকার :)
ডিওন স্যামুয়েল ওয়াশিংটন

4
এই বিষয়ে একটি বিষয় লক্ষণীয়, এটি দেখে মনে হচ্ছে যে আইডি জেনারেটরগুলি "isPostInsertGenerator" == সত্য নয়, ইতিমধ্যে চলবে। আপনি অবিরত থাকার পরেও আইডির মান পরিবর্তন করতে পারেন তবে, আপনি একটি ক্রম সংখ্যা হারাবেন।
gview

15
নতুন সমাধানটি এখন আমাকে একটি মতবাদ স্থিতিতে আইডি সেট করতে দেয়। তবে, $ মেটাডেটা-> সেটআইডিজেনেরেটর টাইপ (\ মতবাদ \ ওআরএম \ ম্যাপিং \ ক্লাসমেটাডাটা :: জেনারেটর_ওয়াইপি_নোন) ব্যবহার করা হচ্ছে; আইডি সেট এবং সংরক্ষণ করার অনুমতি দেয়। (মাইএসকিউএল)
jmoz

4
নতুন সমাধানটি সিমফনি 3.0 তে কাজ করে না। আমার ব্যবহার করতে হয়েছিল$metadata = $this->getEntityManager()->getClassMetaData(User::class); $metadata->setIdGenerator(new AssignedGenerator()); $metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_NONE);
পাইওট্রেইক্লার

উত্তর:


52

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

আমি এই লাইনটি পুরোপুরি কার্যকর করতে এটি যুক্ত করতে চাই:

$metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());

শুভেচ্ছান্তে,


ধন্যবাদ! এটি প্রথম ইস্যু হওয়ার পরে মতবাদ কিছুটা উন্নত হয়েছে, তাই আমি আপনার উত্তর গ্রহণ করেছি এবং সে অনুযায়ী আমার মূল টিকিটটি আপডেট করেছি।
এরিক

আপনাকে ধন্যবাদ এবং আমি যতটা সম্ভব সাহায্য করতে পেরে আনন্দিত :)
নিকোলাসবুই

4
এটি স্থায়ীভাবে এই জেনারেটর সেট করবে? আমি কি জোরপূর্বক আইডি সহ একটি রেকর্ড যুক্ত করতে পারি এবং তারপরে এটিকে স্ব-সংযোজন আইডি ব্যবহার করতে পারি?
পাভেল ডাবিনিন

4
আমি নিশ্চিত করতে পারি যে এটি সিমফনি ৩.২ এর সাথে কাজ করে। তবে আমি যা প্রত্যাশা করিনি, তা হ'ল জেনারেটরটি নির্বাহের পরে সেট করতে হবে $em->persist($entity)
বোডো

30

সম্ভবত যা মতবাদ পরিবর্তিত হয়েছে কিন্তু এখন সঠিক উপায়:

$metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);

4
এটি এখনও প্রাসঙ্গিক তথ্য এবং মতবাদ ২.৪.১ এর জন্য কাজ করে, তবে @ জিফিলিপ দ্বারা উল্লিখিত দ্বিতীয় লাইনটি সরানো উচিত।
মান্টাস

মতবাদ> 2.5 এর জন্য কাজ করে না কারণ ClassMetadataএকটি ইন্টারফেস এবং এর জন্য কোনও ধ্রুবক থাকতে পারে না।
টিএমইএসপি্লায়নার


@ জিফিলিপ দ্বিতীয় লাইনটি গুরুত্বপূর্ণ যদি আপনি এটি সমিতিগুলির সাথে কাজ করতে চান ।
তাজ

4
ব্যবহার করে সহজ করতে পারবেন$metadata::GENERATOR_TYPE_NONE
উইল বি

7

সত্তাটি কোনও শ্রেণি সারণির উত্তরাধিকারের অংশ হিসাবে উভয় সত্তার জন্য শ্রেণি মেটাডেটাতে আপনাকে আইডি-জেনারেটর পরিবর্তন করতে হবে (যে সত্তাটি আপনি স্থির করছেন এবং মূল সত্তা)


আমি মনে করি কেসটি হ'ল আপনাকে কেবলমাত্র মূল সত্তা নির্দিষ্ট করতে হবে। মেটাডাটাফ্যাক্টরি আইডি কৌশল নির্ধারণের সময় উত্তরাধিকার পরীক্ষা করে।
শেঠ ব্যাটিন

আসলে, আমি যখন এটি কেবল মূল সত্তায় যুক্ত করি তখন এটি নির্দোষভাবে কাজ করে। আমি যখন এটি উভয়ের সাথে যুক্ত করি তখন আমি SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint failsত্রুটিগুলি পাচ্ছি । Downvoted
ioleo

5

সমস্ত সমাধান সন্নিবেশ করার আগে আইডি থাকলেই নতুন সমাধান সূক্ষ্মভাবে কাজ করে। যখন একটি সত্তার আইডি থাকে এবং অন্যটির কোনও না থাকে - নতুন সমাধান ব্যর্থ হয়।

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

function createEntity(\Doctrine\ORM\EntityManager $em, $entity, $id = null)
{
    $className = get_class($entity);
    if ($id) {
        $idRef = new \ReflectionProperty($className, "id");
        $idRef->setAccessible(true);
        $idRef->setValue($entity, $id);

        $metadata = $em->getClassMetadata($className);
        /** @var \Doctrine\ORM\Mapping\ClassMetadataInfo $metadata */
        $generator = $metadata->idGenerator;
        $generatorType = $metadata->generatorType;

        $metadata->setIdGenerator(new \Doctrine\ORM\Id\AssignedGenerator());
        $metadata->setIdGeneratorType(\Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_NONE);

        $unitOfWork = $em->getUnitOfWork();
        $persistersRef = new \ReflectionProperty($unitOfWork, "persisters");
        $persistersRef->setAccessible(true);
        $persisters = $persistersRef->getValue($unitOfWork);
        unset($persisters[$className]);
        $persistersRef->setValue($unitOfWork, $persisters);

        $em->persist($entity);
        $em->flush();

        $idRef->setAccessible(false);
        $metadata->setIdGenerator($generator);
        $metadata->setIdGeneratorType($generatorType);

        $persisters = $persistersRef->getValue($unitOfWork);
        unset($persisters[$className]);
        $persistersRef->setValue($unitOfWork, $persisters);
        $persistersRef->setAccessible(false);
    } else {
        $em->persist($entity);
        $em->flush();
    }
}

4

মতবাদ 2.5 এবং মাইএসকিউএল জন্য সমাধান

"নতুন সমাধান" ডক্ট্রিন 2.5 এবং মাইএসকিউএল নিয়ে কাজ করে না। আপনাকে ব্যবহার করতে হবে:

$metadata = $this->getEntityManager()->getClassMetaData(Entity::class);
$metadata->setIdGenerator(new AssignedGenerator());
$metadata->setIdGeneratorType(ClassMetadata::GENERATOR_TYPE_‌​NONE);

তবে আমি কেবল এটি মাইএসকিউএলের জন্যই নিশ্চিত করতে পারি, কারণ আমি এখনও অন্য কোনও ডিবিএমএস চেষ্টা করি নি।


1

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


1

ভিলারম্যানের কাজ থেকে অনুপ্রাণিত হয়ে আমি লাইব্রেরি tseho / মতবাদ-নির্ধারিত-পরিচয় তৈরি করেছি যা আপনাকে ম্যানুয়ালি কোনও মতবাদ আইডি নির্ধারণ করতে দেয়, এমনকি সত্তা অটো, সিকোয়েন্স, আইডেন্টিটি বা ইউআইডি অবস্থা ব্যবহার করে।

আপনার উত্পাদনতে এটি কখনও ব্যবহার করা উচিত নয় তবে এটি কার্যকরী পরীক্ষার জন্য সত্যই কার্যকর।

গ্রন্থাগারটি একটি নির্ধারিত আইডির সাথে সত্তা স্বয়ংক্রিয়ভাবে সত্তাগুলি সনাক্ত করে এবং কেবলমাত্র যখন প্রয়োজন হয় তখন জেনারেটরটি প্রতিস্থাপন করে। পাঠ্যসূচীর প্রাথমিক জেনারেটরটি ফ্যালব্যাক হয়ে যাবে যখন কোনও ইভেন্টের জন্য নির্ধারিত আইডি নেই।

জেনারেটরের প্রতিস্থাপন একটি মতবাদ ইভেন্ট ইভেন্টলিস্টারে ঘটে, আপনার ফিক্সচারগুলিতে কোনও অতিরিক্ত কোড যুক্ত করার দরকার নেই।

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