-1

In defending my question, here are some of the references that I have looked at before posting.

Symfony Doctrine update query fail

Doctrine Is not a valid entity or mapped super class

How to fix class is not a valid entity or mapped super class?

And there were more than a half dozen more that I am not listing. The error message that I am getting this.

[18-Apr-2020 12:30:50 America/New_York] PHP Fatal error:  Uncaught Doctrine\ORM\Mapping\MappingException: Class "Doctrine\ORM\QueryBuilder" is not a valid entity or mapped super class. in C:\oerm_dev\www\dev\future5_2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\MappingException.php:346
Stack trace:
#0 C:\oerm_dev\www\dev\future5_2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\Driver\AnnotationDriver.php(93): Doctrine\ORM\Mapping\MappingException::classIsNotAValidEntityOrMappedSuperClass('Doctrine\\ORM\\Qu...')
#1 C:\oerm_dev\www\dev\future5_2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataFactory.php(151): Doctrine\ORM\Mapping\Driver\AnnotationDriver->loadMetadataForClass('Doctrine\\ORM\\Qu...', Object(Doctrine\ORM\Mapping\ClassMetadata))
#2 C:\oerm_dev\www\dev\future5_2\vendor\doctrine\common\lib\Doctrine\Common\Persistence\Mapping\AbstractClassMetadataFactory.php(332): Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata(Object(Doctrine\ORM\Mapping\ClassMetadata), NULL, false, Array)
#3 C:\oerm_dev\www\dev\future5_2\vendor\doctrine\orm\lib\Doctrine in C:\oerm_dev\www\dev\future5_2\vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\MappingException.php on line 346

In troubleshooting the code I know that it is this line.

$this->_em->persist($qb);

I know it is this line because if I comment out that line and the line below it the code runs through with no additional errors. However, nothing is saved. I have read over

https://www.doctrine-project.org/projects/doctrine-phpcr-odm/en/latest/reference/query-builder.html#the-querybuilder

While there is a lot of information getting data from but there is not a lot written about UPDATE to.

https://symfony.com/doc/current/doctrine.html#updating-an-object

Now here is the code

namespace OpenEMR\Repositories;

use Doctrine\ORM\EntityRepository;
use OpenEMR\Entities\FormEncounter;

class FormEncounterRepository extends EntityRepository
{
    /**
     * @param FormEncounter
     * @param $message
     * @return $response
     */

    public function update($message)
    {
        $response = false;
        $enc = $_SESSION['encounter'];
        try {
            $qb = $this->_em->getRepository($this->_entityName)->createQueryBuilder('fe');
            $qb->update(FormEncounter::class)
                ->set('fe.reason', 'text')
                ->where('fe.encounter', 'num')
                ->setParameter('text', $message)
                ->setParameter('num', $enc)
                ->getQuery();
            $this->_em->persist($qb);
            $this->_em->flush();
            $response = true;
        } catch (Exception $e) {
            return 'An Error occured during save: ' .$e->getMessage();
        }
        return $response;
    }
}

My question is why is this error being thrown? I have code very close to this the uses the insert command and it works. The major difference in the two is that the select uses the Query::HYDRATE_ARRAY function.

Ok I get the point. That was some information that I have not run across. I was doing it wrong.

However, the https://symfony.com/doc/current/doctrine.html#updating-an-object documentation don't tell you that they are persisting because. Now to stop my whining.

I went back in and changed the controller code thinking as was said to persist there and not the Repository. I added a function. Here is my controller code.

 /**
 * @param $message
 */
public function addAddendum(FormEncounter $message)
{
    //get current encounter
    $enc = $GLOBALS['encounter'];
    $reason = $this->repository;
    //get reason from database
    $getReason = $reason->findOneBy(['encounter' => $enc]);
    $this->updatedReason = $getReason->getReason() ."\r\n ADENDUM: \r\n". $message;
    self::updateReason($this->updateReason());

    return "Finished";

}

/**
 * @param \OpenEMR\Entities\FormEncounter $reason
 */
private function updateReason(FormEncounter $reason)
{
    try {
        //get current encounter
        $enc = $GLOBALS['encounter'];
        $aReason = $this->repository;
        $findReason = $aReason->findOneBy(['encounter' => $enc]);
        $this->save = $findReason->setReason($reason);
        $this->entityManager->persist($this->save);
        $this->entityManager->flush();
    } catch (Exception $e) {

    }
}

Now I have a new Error that I can't figure out.

    [18-Apr-2020 20:33:17 America/New_York] PHP Fatal error:  Uncaught Error: Call to a member function persist() on null in C:\oerm_dev\www\dev\future5_2\src\Events\Addendum\AddendumEsign.php:71
Stack trace:
#0 C:\oerm_dev\www\dev\future5_2\src\Events\Addendum\AddendumEsign.php(54): OpenEMR\Events\Addendum\AddendumEsign->updateReason('Test Ribbon, no...')
#1 C:\oerm_dev\www\dev\future5_2\src\Events\Addendum\addendum_esign_helper.php(38): OpenEMR\Events\Addendum\AddendumEsign->addAddendum('This is a test ...')
#2 {main}
  thrown in C:\oerm_dev\www\dev\future5_2\src\Events\Addendum\AddendumEsign.php on line 71

So, check my logic. $findReason makes a call to the database to bring back the reason that I am looking to update. On finding that reason that I want to update. $this->save = $findReason->setReason($reason) should save the new reason object that was passed from the addAddendum() method. The error is telling me that line 71 is null when I know I passed it $reason object.

user1794918
  • 1,131
  • 2
  • 16
  • 34
  • 1
    Why are you persisting the query builder? Persist is for entities – malarzm Apr 18 '20 at 17:39
  • Two things: 1. you are trying to persist a query builder object instead of an entity. 2. a repository class if for organizing your queries, not for updating an entity. This can be done in a controller or in a service. – Dirk J. Faber Apr 18 '20 at 18:56
  • @DirkJ.Faber I moved back to the controller but now I have a null error. What can it be now? – user1794918 Apr 19 '20 at 00:47
  • What is your symfony version? – Arnold Richmon Apr 19 '20 at 03:09
  • 3.4 is the version that is in the program right now. @ArnoldRichmon We are using Symfony components in our program. – user1794918 Apr 19 '20 at 10:38
  • I have found that $this->save is not being set by $findReason->setReason($reason); It is in fact null. So the question now is what is the right way to update an entity value. – user1794918 Apr 19 '20 at 12:34
  • When I var dump $findReason the new reason has been inserted into the object. But persist is still throwing an error of being null. @DirkJ.Faber – user1794918 Apr 19 '20 at 16:36
  • I got it working. The repository is where the "persist" should go. Not in the controller as suggested. I will post the solution as soon as the system allows me to post. – user1794918 Apr 19 '20 at 20:47

1 Answers1

0

Some of this is specific to the program that I am working inside. The error messages are only a guide to help figure out what is wrong. Following the error messages, it became a journey to get to the proper solution in my case.

The purpose of this code is to update a field in a table and save that updated information.

These are the classes. First the controller class.

namespace OpenEMR\Events\Addendum;

use Doctrine\ORM\Mapping as ORM;
use OpenEMR\Common\Database\Connector;
use OpenEMR\Common\Logging\Logger;
use OpenEMR\Entities\FormEncounter;
use OpenEMR\Repositories\FormEncounterRepository;
use Symfony\Component\Config\Definition\Exception\Exception;

class AddendumEsign
{
    /**
     * @var
     */
    private $entityManager;
    private $repository;
    private $updatedReason;


    /**
     * @var string
     * @ORM\Column(type="string")
     */
    public function __construct()
    {
        $this->logger = new Logger(FormEncounterRepository::class);
        $database = Connector::Instance();
        $entityManager = $database->entityManager;
        $this->repository = $entityManager->getRepository(FormEncounter::class);
    }

    /**
     * the addAddendum is passed the addendum to be added to the reason 
     * that is currently in the form_encounter table. This method purpose is to edit
     * the currently stored reason
     */
    /**
     * @param $message
     * @return string
     */
    public function addAddendum($message)
    {
        //get current encounter
        $enc = $GLOBALS['encounter'];
        $reason = $this->repository;   //This is my database connector
        //get reason from database
        $getReason = $reason->findOneBy(['encounter' => $enc]);
        $this->updatedReason = $getReason->getReason() ."\r\n ADENDUM: \r\n". $message;
        self::setReason($this->updatedReason);

        return "Finished";

    }

    /**
     * The purpose of this block is to insert the new reason in to the object.
     * Then it is passed to the reposistory to save / update the reason.
     */
    /**
     * @param $reason
     */
    private function setReason($reason)
    {
        try {
            //get current encounter
            $enc = $GLOBALS['encounter'];
            $aReason = $this->repository;
            $findReason = $aReason->findOneBy(['encounter' => $enc]);
            //update the reason to the new reason for the addendum
            $findReason->setReason($reason);
            //call the reposistory to store the object and pass the object
            $save = $this->repository;
            $updatedReason = $save->update($findReason);
        } catch (Exception $e) {

        }
        return $updatedReason;
    }

}

Now the repository class.

namespace OpenEMR\Repositories;

use Doctrine\ORM\EntityRepository;
use OpenEMR\Entities\FormEncounter;
use Symfony\Component\Config\Definition\Exception\Exception;

class FormEncounterRepository extends EntityRepository
{
    /**
     * @param FormEncounter
     * @param $message
     * @return $response
     */

    public function update($message)
    {
        $response = false;
        try {
            //Since it is already an object ready for storing.
            //Doctrine can figure out from here to replace into database entry.
            //I learned that persist and flush only work in the repository and not in the controller. 
            $result = $this->_em->persist($message);
            $this->_em->flush();
            $response = true;
        } catch (Exception $e) {
            return 'An Error occured during save: ' .$e->getMessage();
        }
        return $response;
    }
}

Hope this helps someone looking for answers on what is possbile.

user1794918
  • 1,131
  • 2
  • 16
  • 34