0

I need to save multiple repository like this, but I need to use to save Id of first repository in second repository and third and fourth one, so I think I can't use the link example with repository. Is there any other way to do this?

For example,

$repositoryOne = $this->repository->save($demo);
$someAnotherObject->setSomeId($repositoryOne->getId());
$repositoryTwo = $this->repository->save($someAnotherObject);
$someAnotherObject->setSomeId($repositoryTwo->getId());
$repositoryThree = $this->repository->save($someAnotherObject);

If some repository failed to save by any reason then It should revert all saved data.

1 Answer 1

1

The code below uses the transaction mechanism. And you're right thinking it looks after the rollback as well.

I found it being used in \Magento\SalesSampleData\Model\Order\Processor::shipOrder. However, under the hood, it is not the repository that saves the data. Instead the objects within the transaction objects are Abstract Model and saved using the old fashion way to save data.

Whilst repository are recommended to save a model. In your instance, I hope it is safe to say your intention to use this transaction mechanism will consolidate your system.

   <?php
    
    namespace Mbs\TransactionSave\Command;
    
    use Magento\Catalog\Api\CategoryRepositoryInterface;
    use Magento\Catalog\Api\ProductRepositoryInterface;
    use Magento\Framework\App\Area;
    use Magento\Framework\DB\TransactionFactory;
    use Magento\Store\Model\Store;
    use Symfony\Component\Console\Command\Command;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    class SaveManyObject extends Command
    {
        /**
         * @var ProductRepositoryInterface
         */
        private $productRepository;
        /**
         * @var CategoryRepositoryInterface
         */
        private $categoryRepository;
        /**
         * @var TransactionFactory
         */
        private $transactionFactory;
        /**
         * @var \Magento\Framework\App\State
         */
        private $state;
    
        public function __construct(
            ProductRepositoryInterface $productRepository,
            CategoryRepositoryInterface $categoryRepository,
            TransactionFactory $transactionFactory,
            \Magento\Framework\App\State $state,
            string $name = null
        ) {
            parent::__construct($name);
            $this->productRepository = $productRepository;
            $this->categoryRepository = $categoryRepository;
            $this->transactionFactory = $transactionFactory;
            $this->state = $state;
        }
    
        protected function configure()
        {
            $this->setName('mbs:transaction:commit');
            $this->setDescription('Save many objects');
        }
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            $this->initialiseAreaCode();
    
            $product = $this->productRepository->get('MH02', true, Store::DEFAULT_STORE_ID);
            $product->setName($product->getName() . ' transaction saved');
    
            $category = $this->categoryRepository->get(4, Store::DEFAULT_STORE_ID);
            $category->setName($category->getName() . ' transaction saved');
    
            $transaction = $this->transactionFactory->create();
            $transaction->addObject($product);
            $transaction->addObject($category);
            $transaction->save();
    
            $productSaved = $this->productRepository->get('MH02');
            $output->writeln(sprintf('product new name: %s', $productSaved->getName()));
            $categorySaved = $this->categoryRepository->get(4);
            $output->writeln(sprintf('category new name: %s', $categorySaved->getName()));
    
            $output->writeln('objects saved');
        }
    
        private function initialiseAreaCode(): void
        {
            try {
                $this->state->setAreaCode(Area::AREA_ADMINHTML);
            } catch (\Exception $e) {
    
            }
        }
    }
3
  • But how can I pass saved Id to next Object? If you see my example you will see $someAnotherObject->setSomeId($repositoryTwo->getId());
    – Max
    Jul 29, 2020 at 15:02
  • the point I am making in my answer is that you do not have to save at all, the transaction will do it for you Jul 29, 2020 at 15:37
  • I know, but I want the Id so I can save Id on another Object :)
    – Max
    Aug 3, 2020 at 21:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.