Not detected new mapped field #6336

Closed
opened 2026-01-22 15:31:13 +01:00 by admin · 19 comments
Owner

Originally created by @nmateo on GitHub (Oct 28, 2019).

Originally assigned to: @Ocramius on GitHub.

Bug Report

Q A
BC Break no
Version 2.4

Summary

I tried to map a field exactly as the same as one another in my entity, when running:

php bin/console doctrine:schema:update --dump-sql
or
php bin/console doctrine:schema:update --force
i got this: [OK] Nothing to update - your database is already in sync with the current entity metadata.
And the field is fine in the database:
image

Te field is "promoted", same as "certified", same behavior expected.

Current behavior

In practice, whenever i try to work with the field "promoted" the same way as i do with the field "certified", it says there's no mapped field "promoted".

How to reproduce

BaseListing.php:

<?php

/*
 * This file is part of the Cocorico package.
 *
 * (c) Cocolabs SAS <contact@cocolabs.io>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Cocorico\ListingBundle\Model;

use Cocorico\ListingBundle\Entity\Listing;
use Cocorico\ListingBundle\Validator\Constraints as CocoricoAssert;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Listing
 *
 * @CocoricoAssert\ListingConstraint()
 *
 * @ORM\MappedSuperclass
 */
abstract class BaseListing
{

    /* Status */
    const STATUS_NEW = 1;
    const STATUS_PUBLISHED = 2;
    const STATUS_INVALIDATED = 3;
    const STATUS_SUSPENDED = 4;
    const STATUS_DELETED = 5;
    const STATUS_TO_VALIDATE = 6;

    public static $statusValues = array(
        self::STATUS_NEW => 'entity.listing.status.new',
        self::STATUS_PUBLISHED => 'entity.listing.status.published',
        self::STATUS_INVALIDATED => 'entity.listing.status.invalidated',
        self::STATUS_SUSPENDED => 'entity.listing.status.suspended',
        self::STATUS_DELETED => 'entity.listing.status.deleted',
        self::STATUS_TO_VALIDATE => 'entity.listing.status.to_validate',
    );

    public static $visibleStatus = array(
        self::STATUS_NEW,
        self::STATUS_PUBLISHED,
        self::STATUS_INVALIDATED,
        self::STATUS_SUSPENDED,
        self::STATUS_TO_VALIDATE,
    );


    /* Type */
    const TYPE_ONE = 1;
    const TYPE_TWO = 2;
    const TYPE_THREE = 3;

    public static $typeValues = array(
        self::TYPE_ONE => 'entity.listing.type.one',
        self::TYPE_TWO => 'entity.listing.type.two',
        self::TYPE_THREE => 'entity.listing.type.three',
    );

    /* Cancellation policy */
    const CANCELLATION_POLICY_FLEXIBLE = 1;
    const CANCELLATION_POLICY_STRICT = 2;

    public static $cancellationPolicyValues = array(
        self::CANCELLATION_POLICY_FLEXIBLE => 'entity.listing.cancellation_policy.flexible',
        self::CANCELLATION_POLICY_STRICT => 'entity.listing.cancellation_policy.strict',
    );

    public static $cancellationPolicyDescriptions = array(
        self::CANCELLATION_POLICY_FLEXIBLE => 'entity.listing.cancellation_policy_desc.flexible',
        self::CANCELLATION_POLICY_STRICT => 'entity.listing.cancellation_policy_desc.strict',
    );

    /**
     * @ORM\Column(name="status", type="smallint", nullable=false)
     *
     * @var integer
     */
    protected $status = self::STATUS_NEW;

    /**
     * @ORM\Column(name="type", type="smallint", nullable=true)
     *
     * @var integer
     */
    protected $type;

    /**
     * @ORM\Column(name="price", type="decimal", precision=8, scale=0, nullable=false)
     * @Assert\NotBlank(message="assert.not_blank")
     *
     * @var integer
     */
    protected $price = 0;

    /**
     * 
     * @ORM\Column(name="certified", type="boolean", nullable=true)
     *
     * @var boolean
     */
    protected $certified;

    /**
     * 
     *
     * @ORM\Column(name="promoted", type="boolean", nullable=true)
     * 
     * @var boolean
     */
    protected $promoted;


    /**
     *
     * @ORM\Column(name="min_duration", type="smallint", nullable=true)
     *
     * @var integer
     */
    protected $minDuration;

    /**
     *
     * @ORM\Column(name="max_duration", type="smallint", nullable=true)
     *
     * @var integer
     */
    protected $maxDuration;

    /**
     *
     * @ORM\Column(name="cancellation_policy", type="smallint", nullable=false)
     * @Assert\NotBlank(message="assert.not_blank")
     *
     * @var integer
     */
    protected $cancellationPolicy = self::CANCELLATION_POLICY_FLEXIBLE;


    /**
     * @ORM\Column(name="average_rating", type="smallint", nullable=true)
     *
     * @var integer
     */
    protected $averageRating;

    /**
     * @ORM\Column(name="comment_count", type="integer", nullable=true)
     *
     * @var integer
     */
    protected $commentCount = 0;

    /**
     * Admin notation
     *
     * @ORM\Column(name="admin_notation", type="decimal", precision=3, scale=1, nullable=true)
     *
     * @var float
     */
    protected $adminNotation;

    /**
     * @ORM\Column(name="availabilities_updated_at", type="datetime", nullable=true)
     *
     * @var \DateTime
     */
    protected $availabilitiesUpdatedAt;

    /**
     * Translation proxy
     *
     * @param $method
     * @param $arguments
     * @return mixed
     */
    public function __call($method, $arguments)
    {
        return $this->proxyCurrentLocaleTranslation($method, $arguments);
    }

    /**
     * Set status
     *
     * @param  integer $status
     * @return $this
     */
    public function setStatus($status)
    {
        if (!in_array($status, array_keys(self::$statusValues))) {
            throw new \InvalidArgumentException(
                sprintf('Invalid value for listing.status : %s.', $status)
            );
        }

        $this->status = $status;

        return $this;
    }

    /**
     * Get status
     *
     * @return integer
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * Get Status Text
     *
     * @return string
     */
    public function getStatusText()
    {
        return self::$statusValues[$this->getStatus()];
    }

    /**
     * Return available status for current status
     *
     * @param int $status
     *
     * @return array
     */
    public static function getAvailableStatusValues($status)
    {
        $availableStatus = array(self::STATUS_DELETED);

        if ($status == self::STATUS_NEW) {
            $availableStatus[] = self::STATUS_PUBLISHED;
        } elseif ($status == self::STATUS_PUBLISHED) {
            $availableStatus[] = self::STATUS_SUSPENDED;
        } elseif ($status == self::STATUS_INVALIDATED) {
            $availableStatus[] = self::STATUS_TO_VALIDATE;
        } elseif ($status == self::STATUS_SUSPENDED) {
            $availableStatus[] = self::STATUS_PUBLISHED;
        }

        //Prepend current status to visible status
        array_unshift($availableStatus, $status);

        //Construct associative array with keys equals to status values and values to label of status
        $status = array_intersect_key(
            self::$statusValues,
            array_flip($availableStatus)
        );

        return $status;
    }


    /**
     * Set price
     *
     * @param  integer $price
     * @return $this
     */
    public function setPrice($price)
    {
        $this->price = $price;

        return $this;
    }

    /**
     * Get price
     *
     * @return string
     */
    public function getPrice()
    {
        return $this->price;
    }

    /**
     * Get price
     *
     * @return float
     */
    public function getPriceDecimal()
    {
        return $this->price / 100;
    }

    /**
     * Get offerer amount fees
     *
     * @param array $feeAsOfferer
     *
     * @return float
     */
    public function getAmountFeeAsOffererDecimal($feeAsOfferer)
    {
        return $this->getPriceDecimal() * $feeAsOfferer['percent'] + $feeAsOfferer['fixed'] / 100;
    }

    /**
     * Get amount to pay to offerer
     *
     * @param array $feeAsOfferer
     *
     * @return float
     */
    public function getAmountToPayToOffererDecimal($feeAsOfferer)
    {
        return $this->getPriceDecimal() - $this->getAmountFeeAsOffererDecimal($feeAsOfferer);
    }

    /**
     * Get amount to pay to offerer minus VAT when listing price is VAT excluded.
     *
     * Return the same result than getAmountToPayToOffererDecimal used with listing price VAT is included:
     * amountToPayVATIncluded = PriceVATIncluded - (PriceVATIncluded * feeAsOfferer)
     * amountToPayVATExcluded = amountToPayVATIncluded / (1 + vatRate)
     *
     * So :
     * amountToPayVATIncluded = ((price * (1 + vatRate)) - (price * (1 + vatRate) * feeAsOfferer))
     * amountToPayVATExcluded = amountToPayVATIncluded / (1 + vatRate)
     * amountToPayVATExcluded = price - price * feeAsOfferer
     * amountToPayVATExcluded = getAmountToPayToOffererDecimal
     *
     *
     * @param array $feeAsOfferer
     *
     * @return int
     */
    public function amountToPayToOffererForPriceExcludingVATDecimal($feeAsOfferer)
    {
        return $this->getAmountToPayToOffererDecimal($feeAsOfferer);
    }

    /**
     * Get offerer amount fees when listing price is VAT excluded.
     * Fees are computed on listing price VAT included
     *
     * @param array $feeAsOfferer
     * @param float $vatRate
     *
     * @return int
     */
    public function getAmountFeeAsOffererForPriceExcludingVATDecimal($feeAsOfferer, $vatRate)
    {
        return $this->getAmountFeeAsOffererDecimal($feeAsOfferer) * (1 + $vatRate);
    }

    /**
     * Return the min listing price according to offerer fees and default min price.
     *
     * @param array $defaultFeeAsOfferer
     * @param int   $defaultMinPrice
     * @return float
     */
    public function getMinPrice($defaultFeeAsOfferer, $defaultMinPrice)
    {
        $result = $defaultMinPrice;
        /** @var  $this Listing */
        $user = $this->getUser();
        if ($user) {
            $feeAsOfferer = $user->getFeeAsOfferer($defaultFeeAsOfferer);
            $result = max(round($feeAsOfferer['fixed'] / (1 - $feeAsOfferer['percent']), 2), $defaultMinPrice);
        }

        return $result;
    }


    /**
     * @param array $defaultFeeAsOfferer
     * @param int   $defaultMinPrice
     * @return float
     */
    public function getMinPriceDecimal($defaultFeeAsOfferer, $defaultMinPrice)
    {
        return $this->getMinPrice($defaultFeeAsOfferer, $defaultMinPrice) / 100;
    }

    /**
     * Check if listing has correct min price according to offerer fees and default min price
     *
     * @param array $defaultFeeAsOfferer
     * @param int   $defaultMinPrice
     * @return bool
     */
    public function hasMinPrice($defaultFeeAsOfferer, $defaultMinPrice)
    {
        if ($defaultMinPrice > 0 || $this->getPrice() > 0) {//if listing is not free or min price > 0
            $minPrice = $this->getMinPrice($defaultFeeAsOfferer, $defaultMinPrice);

            if ($this->getPrice() < $minPrice) {
                return false;
            }
        }

        //else listing is free

        return true;
    }

    /**
     * @return boolean
     */
    public function isCertified()
    {
        return $this->certified;
    }

    /**
     * @param boolean $certified
     */
    public function setCertified($certified)
    {
        $this->certified = $certified;
    }

    /**
     * @return boolean
     */
    public function isPromoted()
    {
        return $this->promoted;
    }

    /**
     * @param boolean $promoted
     */
    public function setPromoted($promoted)
    {
        $this->promoted = $promoted;
    }

    /**
     * @return int
     */
    public function getType()
    {
        return $this->type;
    }

    /**
     * Set type
     *
     * @param  integer $type
     * @return $this
     */
    public function setType($type)
    {
        if (!in_array($type, array_keys(self::$typeValues))) {
            throw new \InvalidArgumentException(
                sprintf('Invalid value for listing.type : %s.', $type)
            );
        }

        $this->type = $type;

        return $this;
    }

    /**
     * Get Type Text
     *
     * @return string
     */
    public function getTypeText()
    {
        return self::$typeValues[$this->getType()];
    }

    /**
     * Get certified
     *
     * @return boolean
     */
    public function getCertified()
    {
        return $this->certified;
    }

    /**
     * Get promoted
     *
     * @return boolean
     */
    public function getPromoted()
    {
        return $this->promoted;
    }

    /**
     * @return int
     */
    public function getMinDuration()
    {
        return $this->minDuration;
    }

    /**
     * @param int $minDuration
     */
    public function setMinDuration($minDuration)
    {
        $this->minDuration = $minDuration;
    }

    /**
     * @return int
     */
    public function getMaxDuration()
    {
        return $this->maxDuration;
    }

    /**
     * @param int $maxDuration
     */
    public function setMaxDuration($maxDuration)
    {
        $this->maxDuration = $maxDuration;
    }

    /**
     * @return int
     */
    public function getCancellationPolicy()
    {
        return $this->cancellationPolicy;
    }

    /**
     * @param int $cancellationPolicy
     *
     * @return BaseListing
     */
    public function setCancellationPolicy($cancellationPolicy)
    {
        if (!in_array($cancellationPolicy, array_keys(self::$cancellationPolicyValues))) {
            throw new \InvalidArgumentException(
                sprintf('Invalid value for listing.status : %s.', $cancellationPolicy)
            );
            //$cancellationPolicy = self::CANCELLATION_POLICY_FLEXIBLE;
        }

        $this->cancellationPolicy = $cancellationPolicy;

        return $this;
    }

    /**
     * Get Cancellation Policy Text
     *
     * @return string
     */
    public function getCancellationPolicyText()
    {
        return self::$cancellationPolicyValues[$this->getCancellationPolicy()];
    }

    /**
     * Get Cancellation Policy Description
     *
     * @return string
     */
    public function getCancellationPolicyDescription()
    {
        return self::$cancellationPolicyDescriptions[$this->getCancellationPolicy()];
    }

    /**
     * Set averageRating
     *
     * @param  integer $averageRating
     * @return $this
     */
    public function setAverageRating($averageRating)
    {
        $this->averageRating = $averageRating;

        return $this;
    }

    /**
     * Get averageRating
     *1
     *
     * @return integer
     */
    public function getAverageRating()
    {
        return $this->averageRating;
    }

    /**
     * Set commentCount
     *
     * @param  integer $commentCount
     * @return $this
     */
    public function setCommentCount($commentCount)
    {
        $this->commentCount = $commentCount;

        return $this;
    }

    /**
     * Get commentCount
     *1
     *
     * @return integer
     */
    public function getCommentCount()
    {
        return $this->commentCount;
    }

    /**
     * @return float
     */
    public function getAdminNotation()
    {
        return $this->adminNotation;
    }

    /**
     * @param float $adminNotation
     */
    public function setAdminNotation($adminNotation)
    {
        $this->adminNotation = $adminNotation;
    }


    /**
     * @return \DateTime
     */
    public function getAvailabilitiesUpdatedAt()
    {
        return $this->availabilitiesUpdatedAt;
    }

    /**
     * @param \DateTime $availabilitiesUpdatedAt
     */
    public function setAvailabilitiesUpdatedAt($availabilitiesUpdatedAt)
    {
        $this->availabilitiesUpdatedAt = $availabilitiesUpdatedAt;
    }

    /**
     * @return bool
     */
    public function hasPrice()
    {
        return $this->getPrice() > 0;
    }
}`

Entity\Listing.php:

`<?php

namespace Cocorico\ListingBundle\Entity;

use Cocorico\BookingBundle\Entity\Booking;
use Cocorico\ListingBundle\Model\BaseListing;
use Cocorico\ListingBundle\Model\ListingOptionInterface;
use Cocorico\ListingCategoryBundle\Entity\ListingListingCategory;
use Cocorico\ListingCharacteristicBundle\Entity\ListingListingCharacteristic;
use Cocorico\ListingDiscountBundle\Entity\ListingDiscount;
use Cocorico\ListingImageBundle\Entity\ListingImage;
use Cocorico\ListingLocationBundle\Entity\ListingLocation;
use Cocorico\MessageBundle\Entity\Thread;
use Cocorico\UserBundle\Entity\User;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use Symfony\Component\Validator\Constraints as Assert;


/**
 * Listing
 *
 * @ORM\Entity(repositoryClass="Cocorico\ListingBundle\Repository\ListingRepository")
 *
 * @ORM\Table(name="listing",indexes={
 *    @ORM\Index(name="created_at_l_idx", columns={"created_at"}),
 *    @ORM\Index(name="status_l_idx", columns={"status"}),
 *    @ORM\Index(name="price_idx", columns={"price"}),
 *    @ORM\Index(name="type_idx", columns={"type"}),
 *    @ORM\Index(name="min_duration_idx", columns={"min_duration"}),
 *    @ORM\Index(name="max_duration_idx", columns={"max_duration"}),
 *    @ORM\Index(name="average_rating_idx", columns={"average_rating"}),
 *    @ORM\Index(name="admin_notation_idx", columns={"admin_notation"}),
 *    @ORM\Index(name="platform_notation_idx", columns={"platform_notation"}),
 *  })
 */
class Listing extends BaseListing
{
    use ORMBehaviors\Timestampable\Timestampable;
    use ORMBehaviors\Translatable\Translatable;

    use \Cocorico\ListingSearchAdvancedBundle\Model\ListingSearchableTrait;
//    use \Cocorico\ListingCategoryFieldBundle\Model\ListingCategoryFieldableTrait;
//    use \Cocorico\DeliveryBundle\Model\ListingDeliverableTrait;
//    use \Cocorico\ListingDepositBundle\Model\ListingDepositableTrait;
//    use \Cocorico\ListingSessionBundle\Model\ListingSessionableTrait;

//    use \Cocorico\ServiceBundle\Model\ListingTrait;
//    use \Cocorico\ListingVideoBundle\Model\ListingVideoTrait;
//    use \Cocorico\CarrierBundle\Model\ListingCarrierableTrait;

    /**
     * @ORM\Id
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\GeneratedValue(strategy="CUSTOM")
     * @ORM\CustomIdGenerator(class="Cocorico\CoreBundle\Model\CustomIdGenerator")
     *
     * @var integer
     */
    protected $id;

    /**
     * @Assert\NotBlank(message="assert.not_blank")
     *
     * @ORM\ManyToOne(targetEntity="Cocorico\UserBundle\Entity\User", inversedBy="listings", cascade={"persist"})
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false, onDelete="CASCADE")
     *
     * @var User
     */
    protected $user;

    /**
     * @ORM\OneToOne(targetEntity="Cocorico\ListingLocationBundle\Entity\ListingLocation", inversedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
     * @ORM\JoinColumn(name="location_id", referencedColumnName="id", onDelete="CASCADE")
     *
     * @var ListingLocation
     **/
    protected $location;

    /**
     * @ORM\OneToMany(targetEntity="Cocorico\ListingCategoryBundle\Entity\ListingListingCategory", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)//, fetch="EAGER"
     *
     */
    protected $listingListingCategories;

    /**
     * For Asserts @see \Cocorico\ListingBundle\Validator\Constraints\ListingValidator
     *
     * @ORM\OneToMany(targetEntity="Cocorico\ListingImageBundle\Entity\ListingImage", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"position" = "asc"})
     */
    protected $images;

    /**
     * @ORM\OneToMany(targetEntity="Cocorico\ListingCharacteristicBundle\Entity\ListingListingCharacteristic", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true) //, fetch="EAGER"
     *
     */
    protected $listingListingCharacteristics;

    /**
     *
     * @ORM\OneToMany(targetEntity="Cocorico\ListingDiscountBundle\Entity\ListingDiscount", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"fromQuantity" = "asc"})
     */
    protected $discounts;


    /**
     * @ORM\OneToMany(targetEntity="Cocorico\BookingBundle\Entity\Booking", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"createdAt" = "desc"})
     */
    protected $bookings;

    /**
     * @ORM\OneToMany(targetEntity="Cocorico\MessageBundle\Entity\Thread", mappedBy="listing", cascade={"remove"}, orphanRemoval=true)
     * @ORM\OrderBy({"createdAt" = "desc"})
     */
    protected $threads;

    /**
     *
     * @ORM\OneToMany(targetEntity="Cocorico\ListingBundle\Model\ListingOptionInterface", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)
     */
    protected $options;


    public function __construct()
    {
        $this->images = new ArrayCollection();
        $this->listingListingCharacteristics = new ArrayCollection();
        $this->listingListingCategories = new ArrayCollection();
        $this->discounts = new ArrayCollection();
        $this->bookings = new ArrayCollection();
        $this->threads = new ArrayCollection();
        $this->options = new ArrayCollection();
    }


    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Add characteristics
     *
     * @param  ListingListingCharacteristic $listingListingCharacteristic
     * @return Listing
     */
    public function addListingListingCharacteristic(ListingListingCharacteristic $listingListingCharacteristic)
    {
        $this->listingListingCharacteristics[] = $listingListingCharacteristic;

        return $this;
    }


    /**
     * Remove characteristics
     *
     * @param ListingListingCharacteristic $listingListingCharacteristic
     */
    public function removeListingListingCharacteristic(ListingListingCharacteristic $listingListingCharacteristic)
    {
        $this->listingListingCharacteristics->removeElement($listingListingCharacteristic);
        $listingListingCharacteristic->setListing(null);
    }

    /**
     * Get characteristics
     *
     * @return \Doctrine\Common\Collections\Collection|ListingListingCharacteristic[]
     */
    public function getListingListingCharacteristics()
    {
        return $this->listingListingCharacteristics;
    }

    /**
     * Get characteristics ordered by Group and Characteristic
     *
     * @return ArrayCollection
     */
    public function getListingListingCharacteristicsOrderedByGroup()
    {
        $iterator = $this->listingListingCharacteristics->getIterator();
        $iterator->uasort(
            function ($a, $b) {
                /**
                 * @var ListingListingCharacteristic $a
                 * @var ListingListingCharacteristic $b
                 */
                $groupPosA = $a->getListingCharacteristic()->getListingCharacteristicGroup()->getPosition();
                $groupPosB = $b->getListingCharacteristic()->getListingCharacteristicGroup()->getPosition();

                $characteristicPosA = $a->getListingCharacteristic()->getPosition();
                $characteristicPosB = $b->getListingCharacteristic()->getPosition();
                if ($groupPosA == $groupPosB) {
                    if ($characteristicPosA == $characteristicPosB) {
                        return 0;
                    }

                    return ($characteristicPosA < $characteristicPosB) ? -1 : 1;
                }

                return ($groupPosA < $groupPosB) ? -1 : 1;
            }
        );

        return new ArrayCollection(iterator_to_array($iterator));
    }

    /**
     * Add characteristics
     *
     * @param  ListingListingCharacteristic $listingListingCharacteristic
     * @return Listing
     */
    public function addListingListingCharacteristicsOrderedByGroup(
        ListingListingCharacteristic $listingListingCharacteristic
    ) {
        return $this->addListingListingCharacteristic($listingListingCharacteristic);
    }


    /**
     * Remove characteristics
     *
     * @param ListingListingCharacteristic $listingListingCharacteristic
     */
    public function removeListingListingCharacteristicsOrderedByGroup(
        ListingListingCharacteristic $listingListingCharacteristic
    ) {
        $this->removeListingListingCharacteristic($listingListingCharacteristic);
    }


    /**
     * Add category
     *
     * @param  ListingListingCategory $listingListingCategory
     * @return Listing
     */
    public function addListingListingCategory(ListingListingCategory $listingListingCategory)
    {
        $listingListingCategory->setListing($this);
        $this->listingListingCategories[] = $listingListingCategory;

        return $this;
    }


    /**
     * Remove category
     *
     * @param ListingListingCategory $listingListingCategory
     */
    public function removeListingListingCategory(ListingListingCategory $listingListingCategory)
    {
//        foreach ($listingListingCategory->getValues() as $value) {
//            $listingListingCategory->removeValue($value);
//        }

        $this->listingListingCategories->removeElement($listingListingCategory);
    }

    /**
     * Get categories
     *
     * @return \Doctrine\Common\Collections\Collection|ListingListingCategory[]
     */
    public function getListingListingCategories()
    {
        return $this->listingListingCategories;
    }


    /**
     * Set user
     *
     * @param  \Cocorico\UserBundle\Entity\User $user
     * @return Listing
     */
    public function setUser(User $user = null)
    {
        $this->user = $user;

        return $this;
    }

    /**
     * Get user
     *
     * @return \Cocorico\UserBundle\Entity\User
     */
    public function getUser()
    {
        return $this->user;
    }

}

Expected behavior

I excepted doctrine to query for "promoted" the same way as "certified", instead, it says it is'nt mapped, for more info, here's my post on stack overflow: https://stackoverflow.com/questions/58504171/why-isnt-my-property-mapped-to-the-entity

Originally created by @nmateo on GitHub (Oct 28, 2019). Originally assigned to: @Ocramius on GitHub. ### Bug Report <!-- Fill in the relevant information below to help triage your issue. --> | Q | A |------------ | ------ | BC Break | no | Version | 2.4 #### Summary I tried to map a field exactly as the same as one another in my entity, when running: php bin/console doctrine:schema:update --dump-sql or php bin/console doctrine:schema:update --force i got this: [OK] Nothing to update - your database is already in sync with the current entity metadata. And the field is fine in the database: ![image](https://user-images.githubusercontent.com/9270970/67697636-2827d880-f9a9-11e9-8d0f-c3a5955ff9c7.png) Te field is "promoted", same as "certified", same behavior expected. #### Current behavior In practice, whenever i try to work with the field "promoted" the same way as i do with the field "certified", it says there's no mapped field "promoted". #### How to reproduce BaseListing.php: ```php <?php /* * This file is part of the Cocorico package. * * (c) Cocolabs SAS <contact@cocolabs.io> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Cocorico\ListingBundle\Model; use Cocorico\ListingBundle\Entity\Listing; use Cocorico\ListingBundle\Validator\Constraints as CocoricoAssert; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; /** * Listing * * @CocoricoAssert\ListingConstraint() * * @ORM\MappedSuperclass */ abstract class BaseListing { /* Status */ const STATUS_NEW = 1; const STATUS_PUBLISHED = 2; const STATUS_INVALIDATED = 3; const STATUS_SUSPENDED = 4; const STATUS_DELETED = 5; const STATUS_TO_VALIDATE = 6; public static $statusValues = array( self::STATUS_NEW => 'entity.listing.status.new', self::STATUS_PUBLISHED => 'entity.listing.status.published', self::STATUS_INVALIDATED => 'entity.listing.status.invalidated', self::STATUS_SUSPENDED => 'entity.listing.status.suspended', self::STATUS_DELETED => 'entity.listing.status.deleted', self::STATUS_TO_VALIDATE => 'entity.listing.status.to_validate', ); public static $visibleStatus = array( self::STATUS_NEW, self::STATUS_PUBLISHED, self::STATUS_INVALIDATED, self::STATUS_SUSPENDED, self::STATUS_TO_VALIDATE, ); /* Type */ const TYPE_ONE = 1; const TYPE_TWO = 2; const TYPE_THREE = 3; public static $typeValues = array( self::TYPE_ONE => 'entity.listing.type.one', self::TYPE_TWO => 'entity.listing.type.two', self::TYPE_THREE => 'entity.listing.type.three', ); /* Cancellation policy */ const CANCELLATION_POLICY_FLEXIBLE = 1; const CANCELLATION_POLICY_STRICT = 2; public static $cancellationPolicyValues = array( self::CANCELLATION_POLICY_FLEXIBLE => 'entity.listing.cancellation_policy.flexible', self::CANCELLATION_POLICY_STRICT => 'entity.listing.cancellation_policy.strict', ); public static $cancellationPolicyDescriptions = array( self::CANCELLATION_POLICY_FLEXIBLE => 'entity.listing.cancellation_policy_desc.flexible', self::CANCELLATION_POLICY_STRICT => 'entity.listing.cancellation_policy_desc.strict', ); /** * @ORM\Column(name="status", type="smallint", nullable=false) * * @var integer */ protected $status = self::STATUS_NEW; /** * @ORM\Column(name="type", type="smallint", nullable=true) * * @var integer */ protected $type; /** * @ORM\Column(name="price", type="decimal", precision=8, scale=0, nullable=false) * @Assert\NotBlank(message="assert.not_blank") * * @var integer */ protected $price = 0; /** * * @ORM\Column(name="certified", type="boolean", nullable=true) * * @var boolean */ protected $certified; /** * * * @ORM\Column(name="promoted", type="boolean", nullable=true) * * @var boolean */ protected $promoted; /** * * @ORM\Column(name="min_duration", type="smallint", nullable=true) * * @var integer */ protected $minDuration; /** * * @ORM\Column(name="max_duration", type="smallint", nullable=true) * * @var integer */ protected $maxDuration; /** * * @ORM\Column(name="cancellation_policy", type="smallint", nullable=false) * @Assert\NotBlank(message="assert.not_blank") * * @var integer */ protected $cancellationPolicy = self::CANCELLATION_POLICY_FLEXIBLE; /** * @ORM\Column(name="average_rating", type="smallint", nullable=true) * * @var integer */ protected $averageRating; /** * @ORM\Column(name="comment_count", type="integer", nullable=true) * * @var integer */ protected $commentCount = 0; /** * Admin notation * * @ORM\Column(name="admin_notation", type="decimal", precision=3, scale=1, nullable=true) * * @var float */ protected $adminNotation; /** * @ORM\Column(name="availabilities_updated_at", type="datetime", nullable=true) * * @var \DateTime */ protected $availabilitiesUpdatedAt; /** * Translation proxy * * @param $method * @param $arguments * @return mixed */ public function __call($method, $arguments) { return $this->proxyCurrentLocaleTranslation($method, $arguments); } /** * Set status * * @param integer $status * @return $this */ public function setStatus($status) { if (!in_array($status, array_keys(self::$statusValues))) { throw new \InvalidArgumentException( sprintf('Invalid value for listing.status : %s.', $status) ); } $this->status = $status; return $this; } /** * Get status * * @return integer */ public function getStatus() { return $this->status; } /** * Get Status Text * * @return string */ public function getStatusText() { return self::$statusValues[$this->getStatus()]; } /** * Return available status for current status * * @param int $status * * @return array */ public static function getAvailableStatusValues($status) { $availableStatus = array(self::STATUS_DELETED); if ($status == self::STATUS_NEW) { $availableStatus[] = self::STATUS_PUBLISHED; } elseif ($status == self::STATUS_PUBLISHED) { $availableStatus[] = self::STATUS_SUSPENDED; } elseif ($status == self::STATUS_INVALIDATED) { $availableStatus[] = self::STATUS_TO_VALIDATE; } elseif ($status == self::STATUS_SUSPENDED) { $availableStatus[] = self::STATUS_PUBLISHED; } //Prepend current status to visible status array_unshift($availableStatus, $status); //Construct associative array with keys equals to status values and values to label of status $status = array_intersect_key( self::$statusValues, array_flip($availableStatus) ); return $status; } /** * Set price * * @param integer $price * @return $this */ public function setPrice($price) { $this->price = $price; return $this; } /** * Get price * * @return string */ public function getPrice() { return $this->price; } /** * Get price * * @return float */ public function getPriceDecimal() { return $this->price / 100; } /** * Get offerer amount fees * * @param array $feeAsOfferer * * @return float */ public function getAmountFeeAsOffererDecimal($feeAsOfferer) { return $this->getPriceDecimal() * $feeAsOfferer['percent'] + $feeAsOfferer['fixed'] / 100; } /** * Get amount to pay to offerer * * @param array $feeAsOfferer * * @return float */ public function getAmountToPayToOffererDecimal($feeAsOfferer) { return $this->getPriceDecimal() - $this->getAmountFeeAsOffererDecimal($feeAsOfferer); } /** * Get amount to pay to offerer minus VAT when listing price is VAT excluded. * * Return the same result than getAmountToPayToOffererDecimal used with listing price VAT is included: * amountToPayVATIncluded = PriceVATIncluded - (PriceVATIncluded * feeAsOfferer) * amountToPayVATExcluded = amountToPayVATIncluded / (1 + vatRate) * * So : * amountToPayVATIncluded = ((price * (1 + vatRate)) - (price * (1 + vatRate) * feeAsOfferer)) * amountToPayVATExcluded = amountToPayVATIncluded / (1 + vatRate) * amountToPayVATExcluded = price - price * feeAsOfferer * amountToPayVATExcluded = getAmountToPayToOffererDecimal * * * @param array $feeAsOfferer * * @return int */ public function amountToPayToOffererForPriceExcludingVATDecimal($feeAsOfferer) { return $this->getAmountToPayToOffererDecimal($feeAsOfferer); } /** * Get offerer amount fees when listing price is VAT excluded. * Fees are computed on listing price VAT included * * @param array $feeAsOfferer * @param float $vatRate * * @return int */ public function getAmountFeeAsOffererForPriceExcludingVATDecimal($feeAsOfferer, $vatRate) { return $this->getAmountFeeAsOffererDecimal($feeAsOfferer) * (1 + $vatRate); } /** * Return the min listing price according to offerer fees and default min price. * * @param array $defaultFeeAsOfferer * @param int $defaultMinPrice * @return float */ public function getMinPrice($defaultFeeAsOfferer, $defaultMinPrice) { $result = $defaultMinPrice; /** @var $this Listing */ $user = $this->getUser(); if ($user) { $feeAsOfferer = $user->getFeeAsOfferer($defaultFeeAsOfferer); $result = max(round($feeAsOfferer['fixed'] / (1 - $feeAsOfferer['percent']), 2), $defaultMinPrice); } return $result; } /** * @param array $defaultFeeAsOfferer * @param int $defaultMinPrice * @return float */ public function getMinPriceDecimal($defaultFeeAsOfferer, $defaultMinPrice) { return $this->getMinPrice($defaultFeeAsOfferer, $defaultMinPrice) / 100; } /** * Check if listing has correct min price according to offerer fees and default min price * * @param array $defaultFeeAsOfferer * @param int $defaultMinPrice * @return bool */ public function hasMinPrice($defaultFeeAsOfferer, $defaultMinPrice) { if ($defaultMinPrice > 0 || $this->getPrice() > 0) {//if listing is not free or min price > 0 $minPrice = $this->getMinPrice($defaultFeeAsOfferer, $defaultMinPrice); if ($this->getPrice() < $minPrice) { return false; } } //else listing is free return true; } /** * @return boolean */ public function isCertified() { return $this->certified; } /** * @param boolean $certified */ public function setCertified($certified) { $this->certified = $certified; } /** * @return boolean */ public function isPromoted() { return $this->promoted; } /** * @param boolean $promoted */ public function setPromoted($promoted) { $this->promoted = $promoted; } /** * @return int */ public function getType() { return $this->type; } /** * Set type * * @param integer $type * @return $this */ public function setType($type) { if (!in_array($type, array_keys(self::$typeValues))) { throw new \InvalidArgumentException( sprintf('Invalid value for listing.type : %s.', $type) ); } $this->type = $type; return $this; } /** * Get Type Text * * @return string */ public function getTypeText() { return self::$typeValues[$this->getType()]; } /** * Get certified * * @return boolean */ public function getCertified() { return $this->certified; } /** * Get promoted * * @return boolean */ public function getPromoted() { return $this->promoted; } /** * @return int */ public function getMinDuration() { return $this->minDuration; } /** * @param int $minDuration */ public function setMinDuration($minDuration) { $this->minDuration = $minDuration; } /** * @return int */ public function getMaxDuration() { return $this->maxDuration; } /** * @param int $maxDuration */ public function setMaxDuration($maxDuration) { $this->maxDuration = $maxDuration; } /** * @return int */ public function getCancellationPolicy() { return $this->cancellationPolicy; } /** * @param int $cancellationPolicy * * @return BaseListing */ public function setCancellationPolicy($cancellationPolicy) { if (!in_array($cancellationPolicy, array_keys(self::$cancellationPolicyValues))) { throw new \InvalidArgumentException( sprintf('Invalid value for listing.status : %s.', $cancellationPolicy) ); //$cancellationPolicy = self::CANCELLATION_POLICY_FLEXIBLE; } $this->cancellationPolicy = $cancellationPolicy; return $this; } /** * Get Cancellation Policy Text * * @return string */ public function getCancellationPolicyText() { return self::$cancellationPolicyValues[$this->getCancellationPolicy()]; } /** * Get Cancellation Policy Description * * @return string */ public function getCancellationPolicyDescription() { return self::$cancellationPolicyDescriptions[$this->getCancellationPolicy()]; } /** * Set averageRating * * @param integer $averageRating * @return $this */ public function setAverageRating($averageRating) { $this->averageRating = $averageRating; return $this; } /** * Get averageRating *1 * * @return integer */ public function getAverageRating() { return $this->averageRating; } /** * Set commentCount * * @param integer $commentCount * @return $this */ public function setCommentCount($commentCount) { $this->commentCount = $commentCount; return $this; } /** * Get commentCount *1 * * @return integer */ public function getCommentCount() { return $this->commentCount; } /** * @return float */ public function getAdminNotation() { return $this->adminNotation; } /** * @param float $adminNotation */ public function setAdminNotation($adminNotation) { $this->adminNotation = $adminNotation; } /** * @return \DateTime */ public function getAvailabilitiesUpdatedAt() { return $this->availabilitiesUpdatedAt; } /** * @param \DateTime $availabilitiesUpdatedAt */ public function setAvailabilitiesUpdatedAt($availabilitiesUpdatedAt) { $this->availabilitiesUpdatedAt = $availabilitiesUpdatedAt; } /** * @return bool */ public function hasPrice() { return $this->getPrice() > 0; } }` Entity\Listing.php: `<?php namespace Cocorico\ListingBundle\Entity; use Cocorico\BookingBundle\Entity\Booking; use Cocorico\ListingBundle\Model\BaseListing; use Cocorico\ListingBundle\Model\ListingOptionInterface; use Cocorico\ListingCategoryBundle\Entity\ListingListingCategory; use Cocorico\ListingCharacteristicBundle\Entity\ListingListingCharacteristic; use Cocorico\ListingDiscountBundle\Entity\ListingDiscount; use Cocorico\ListingImageBundle\Entity\ListingImage; use Cocorico\ListingLocationBundle\Entity\ListingLocation; use Cocorico\MessageBundle\Entity\Thread; use Cocorico\UserBundle\Entity\User; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use Knp\DoctrineBehaviors\Model as ORMBehaviors; use Symfony\Component\Validator\Constraints as Assert; /** * Listing * * @ORM\Entity(repositoryClass="Cocorico\ListingBundle\Repository\ListingRepository") * * @ORM\Table(name="listing",indexes={ * @ORM\Index(name="created_at_l_idx", columns={"created_at"}), * @ORM\Index(name="status_l_idx", columns={"status"}), * @ORM\Index(name="price_idx", columns={"price"}), * @ORM\Index(name="type_idx", columns={"type"}), * @ORM\Index(name="min_duration_idx", columns={"min_duration"}), * @ORM\Index(name="max_duration_idx", columns={"max_duration"}), * @ORM\Index(name="average_rating_idx", columns={"average_rating"}), * @ORM\Index(name="admin_notation_idx", columns={"admin_notation"}), * @ORM\Index(name="platform_notation_idx", columns={"platform_notation"}), * }) */ class Listing extends BaseListing { use ORMBehaviors\Timestampable\Timestampable; use ORMBehaviors\Translatable\Translatable; use \Cocorico\ListingSearchAdvancedBundle\Model\ListingSearchableTrait; // use \Cocorico\ListingCategoryFieldBundle\Model\ListingCategoryFieldableTrait; // use \Cocorico\DeliveryBundle\Model\ListingDeliverableTrait; // use \Cocorico\ListingDepositBundle\Model\ListingDepositableTrait; // use \Cocorico\ListingSessionBundle\Model\ListingSessionableTrait; // use \Cocorico\ServiceBundle\Model\ListingTrait; // use \Cocorico\ListingVideoBundle\Model\ListingVideoTrait; // use \Cocorico\CarrierBundle\Model\ListingCarrierableTrait; /** * @ORM\Id * @ORM\Column(name="id", type="integer", nullable=false) * @ORM\GeneratedValue(strategy="CUSTOM") * @ORM\CustomIdGenerator(class="Cocorico\CoreBundle\Model\CustomIdGenerator") * * @var integer */ protected $id; /** * @Assert\NotBlank(message="assert.not_blank") * * @ORM\ManyToOne(targetEntity="Cocorico\UserBundle\Entity\User", inversedBy="listings", cascade={"persist"}) * @ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false, onDelete="CASCADE") * * @var User */ protected $user; /** * @ORM\OneToOne(targetEntity="Cocorico\ListingLocationBundle\Entity\ListingLocation", inversedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\JoinColumn(name="location_id", referencedColumnName="id", onDelete="CASCADE") * * @var ListingLocation **/ protected $location; /** * @ORM\OneToMany(targetEntity="Cocorico\ListingCategoryBundle\Entity\ListingListingCategory", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true)//, fetch="EAGER" * */ protected $listingListingCategories; /** * For Asserts @see \Cocorico\ListingBundle\Validator\Constraints\ListingValidator * * @ORM\OneToMany(targetEntity="Cocorico\ListingImageBundle\Entity\ListingImage", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\OrderBy({"position" = "asc"}) */ protected $images; /** * @ORM\OneToMany(targetEntity="Cocorico\ListingCharacteristicBundle\Entity\ListingListingCharacteristic", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true) //, fetch="EAGER" * */ protected $listingListingCharacteristics; /** * * @ORM\OneToMany(targetEntity="Cocorico\ListingDiscountBundle\Entity\ListingDiscount", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\OrderBy({"fromQuantity" = "asc"}) */ protected $discounts; /** * @ORM\OneToMany(targetEntity="Cocorico\BookingBundle\Entity\Booking", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\OrderBy({"createdAt" = "desc"}) */ protected $bookings; /** * @ORM\OneToMany(targetEntity="Cocorico\MessageBundle\Entity\Thread", mappedBy="listing", cascade={"remove"}, orphanRemoval=true) * @ORM\OrderBy({"createdAt" = "desc"}) */ protected $threads; /** * * @ORM\OneToMany(targetEntity="Cocorico\ListingBundle\Model\ListingOptionInterface", mappedBy="listing", cascade={"persist", "remove"}, orphanRemoval=true) */ protected $options; public function __construct() { $this->images = new ArrayCollection(); $this->listingListingCharacteristics = new ArrayCollection(); $this->listingListingCategories = new ArrayCollection(); $this->discounts = new ArrayCollection(); $this->bookings = new ArrayCollection(); $this->threads = new ArrayCollection(); $this->options = new ArrayCollection(); } /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * Add characteristics * * @param ListingListingCharacteristic $listingListingCharacteristic * @return Listing */ public function addListingListingCharacteristic(ListingListingCharacteristic $listingListingCharacteristic) { $this->listingListingCharacteristics[] = $listingListingCharacteristic; return $this; } /** * Remove characteristics * * @param ListingListingCharacteristic $listingListingCharacteristic */ public function removeListingListingCharacteristic(ListingListingCharacteristic $listingListingCharacteristic) { $this->listingListingCharacteristics->removeElement($listingListingCharacteristic); $listingListingCharacteristic->setListing(null); } /** * Get characteristics * * @return \Doctrine\Common\Collections\Collection|ListingListingCharacteristic[] */ public function getListingListingCharacteristics() { return $this->listingListingCharacteristics; } /** * Get characteristics ordered by Group and Characteristic * * @return ArrayCollection */ public function getListingListingCharacteristicsOrderedByGroup() { $iterator = $this->listingListingCharacteristics->getIterator(); $iterator->uasort( function ($a, $b) { /** * @var ListingListingCharacteristic $a * @var ListingListingCharacteristic $b */ $groupPosA = $a->getListingCharacteristic()->getListingCharacteristicGroup()->getPosition(); $groupPosB = $b->getListingCharacteristic()->getListingCharacteristicGroup()->getPosition(); $characteristicPosA = $a->getListingCharacteristic()->getPosition(); $characteristicPosB = $b->getListingCharacteristic()->getPosition(); if ($groupPosA == $groupPosB) { if ($characteristicPosA == $characteristicPosB) { return 0; } return ($characteristicPosA < $characteristicPosB) ? -1 : 1; } return ($groupPosA < $groupPosB) ? -1 : 1; } ); return new ArrayCollection(iterator_to_array($iterator)); } /** * Add characteristics * * @param ListingListingCharacteristic $listingListingCharacteristic * @return Listing */ public function addListingListingCharacteristicsOrderedByGroup( ListingListingCharacteristic $listingListingCharacteristic ) { return $this->addListingListingCharacteristic($listingListingCharacteristic); } /** * Remove characteristics * * @param ListingListingCharacteristic $listingListingCharacteristic */ public function removeListingListingCharacteristicsOrderedByGroup( ListingListingCharacteristic $listingListingCharacteristic ) { $this->removeListingListingCharacteristic($listingListingCharacteristic); } /** * Add category * * @param ListingListingCategory $listingListingCategory * @return Listing */ public function addListingListingCategory(ListingListingCategory $listingListingCategory) { $listingListingCategory->setListing($this); $this->listingListingCategories[] = $listingListingCategory; return $this; } /** * Remove category * * @param ListingListingCategory $listingListingCategory */ public function removeListingListingCategory(ListingListingCategory $listingListingCategory) { // foreach ($listingListingCategory->getValues() as $value) { // $listingListingCategory->removeValue($value); // } $this->listingListingCategories->removeElement($listingListingCategory); } /** * Get categories * * @return \Doctrine\Common\Collections\Collection|ListingListingCategory[] */ public function getListingListingCategories() { return $this->listingListingCategories; } /** * Set user * * @param \Cocorico\UserBundle\Entity\User $user * @return Listing */ public function setUser(User $user = null) { $this->user = $user; return $this; } /** * Get user * * @return \Cocorico\UserBundle\Entity\User */ public function getUser() { return $this->user; } } ``` #### Expected behavior I excepted doctrine to query for "promoted" the same way as "certified", instead, it says it is'nt mapped, for more info, here's my post on stack overflow: https://stackoverflow.com/questions/58504171/why-isnt-my-property-mapped-to-the-entity
admin added the Missing TestsQuestion labels 2026-01-22 15:31:13 +01:00
admin closed this issue 2026-01-22 15:31:14 +01:00
Author
Owner

@nmateo commented on GitHub (Oct 28, 2019):

Sorry for the code blocks, it doesnt work..

@nmateo commented on GitHub (Oct 28, 2019): Sorry for the code blocks, it doesnt work..
Author
Owner

@lcobucci commented on GitHub (Oct 28, 2019):

Did you perhaps have a typo in the version you're using? If not, is this reproducible on the latest version of the ORM (v2.6.4)? v2.4 is pretty much ancient and no longer maintained.

@lcobucci commented on GitHub (Oct 28, 2019): Did you perhaps have a typo in the version you're using? If not, is this reproducible on the latest version of the ORM (v2.6.4)? v2.4 is pretty much ancient and no longer maintained.
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

Did you perhaps have a typo in the version you're using? If not, is this reproducible on the latest version of the ORM (v2.6.4)? v2.4 is pretty much ancient and no longer maintained.

hey thanks, i got this in my composer.lock: "doctrine/orm": "^2.5",

@nmateo commented on GitHub (Oct 29, 2019): > Did you perhaps have a typo in the version you're using? If not, is this reproducible on the latest version of the ORM (v2.6.4)? v2.4 is pretty much ancient and no longer maintained. hey thanks, i got this in my composer.lock: "doctrine/orm": "^2.5",
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

The composer show command grep doctrine give me this:

image

@nmateo commented on GitHub (Oct 29, 2019): The composer show command grep doctrine give me this: ![image](https://user-images.githubusercontent.com/9270970/67755025-b64aa000-fa37-11e9-8e29-9edee8b2f320.png)
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

I also got this composer.json here in vendor/sonata-project/admin-bundle/composer.json:

{
"name": "sonata-project/admin-bundle",
"type": "symfony-bundle",
"description": "The missing Symfony Admin Generator",
"keywords": [
"Admin Generator",
"admin",
"sonata",
"bootstrap"
],
"homepage": "https://sonata-project.org/bundles/admin",
"license": "MIT",
"authors": [
{
"name": "Thomas Rabaix",
"email": "thomas.rabaix@sonata-project.org",
"homepage": "https://sonata-project.org"
},
{
"name": "Sonata Community",
"homepage": "https://github.com/sonata-project/SonataAdminBundle/contributors"
}
],
"require": {
"php": "^5.6 || ^7.0",
"doctrine/common": "^2.7",
"doctrine/inflector": "^1.1",
"knplabs/knp-menu-bundle": "^2.2",
"sonata-project/block-bundle": "^3.11",
"sonata-project/core-bundle": "^3.9",
"sonata-project/exporter": "^1.8",
"symfony/asset": "^2.8 || ^3.2 || ^4.0",
"symfony/config": "^2.8 || ^3.2 || ^4.0",
"symfony/console": "^2.8 || ^3.2 || ^4.0",
"symfony/dependency-injection": "^2.8 || ^3.2 || ^4.0",
"symfony/event-dispatcher": "^2.8 || ^3.2 || ^4.0",
"symfony/expression-language": "^2.8 || ^3.2 || ^4.0",
"symfony/form": "^2.8 || ^3.2 || ^4.0",
"symfony/framework-bundle": "^2.8 || ^3.2 || ^4.0",
"symfony/http-foundation": "^2.8 || ^3.2 || ^4.0",
"symfony/http-kernel": "^2.8 || ^3.2 || ^4.0",
"symfony/options-resolver": "^2.8 || ^3.2 || ^4.0",
"symfony/property-access": "^2.8 || ^3.2 || ^4.0",
"symfony/routing": "^2.8 || ^3.2 || ^4.0",
"symfony/security-acl": "^2.8 || ^3.0",
"symfony/security-bundle": "^2.8 || ^3.2 || ^4.0",
"symfony/security-core": "^2.8 || ^3.2 || ^4.0",
"symfony/security-csrf": "^2.8 || ^3.2 || ^4.0",
"symfony/templating": "^2.8 || ^3.2 || ^4.0",
"symfony/translation": "^2.8 || ^3.2 || ^4.0",
"symfony/twig-bridge": "^2.8 || ^3.2 || ^4.0",
"symfony/twig-bundle": "^2.8 || ^3.2 || ^4.0",
"symfony/validator": "^2.8 || ^3.2 || ^4.0",
"twig/extensions": "^1.5",
"twig/twig": "^1.34 || ^2.0"
},"conflict": {
"jms/di-extra-bundle": "<1.9",
"sonata-project/media-bundle": "<3.7",
"sonata-project/user-bundle": "<3.3"
},
"require-dev": {
"jms/di-extra-bundle": "^1.9",
"jms/translation-bundle": "^1.4",
"matthiasnoback/symfony-dependency-injection-test": "^1.1",
"sensio/generator-bundle": "^3.1",
"sonata-project/intl-bundle": "^2.4",
"symfony/class-loader": "^2.8 || ^3.2",
"symfony/filesystem": "^2.8 || ^3.2 || ^4.0",
"symfony/phpunit-bridge": "^4.0",
"symfony/yaml": "^2.8 || ^3.2 || ^4.0"
},
"suggest": {
"jms/di-extra-bundle": "Annotations for Admin definition",
"jms/translation-bundle": "Extract message keys from Admins",
"sensio/generator-bundle": "Add sonata:admin:generate command",
"sonata-project/intl-bundle": "Add localized date and number into the list"
},
"config": {
"sort-packages": true
},
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Sonata\AdminBundle\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Sonata\AdminBundle\Tests\": "tests/"
}
}
}

@nmateo commented on GitHub (Oct 29, 2019): I also got this composer.json here in vendor/sonata-project/admin-bundle/composer.json: > { "name": "sonata-project/admin-bundle", "type": "symfony-bundle", "description": "The missing Symfony Admin Generator", "keywords": [ "Admin Generator", "admin", "sonata", "bootstrap" ], "homepage": "https://sonata-project.org/bundles/admin", "license": "MIT", "authors": [ { "name": "Thomas Rabaix", "email": "thomas.rabaix@sonata-project.org", "homepage": "https://sonata-project.org" }, { "name": "Sonata Community", "homepage": "https://github.com/sonata-project/SonataAdminBundle/contributors" } ], "require": { "php": "^5.6 || ^7.0", "doctrine/common": "^2.7", "doctrine/inflector": "^1.1", "knplabs/knp-menu-bundle": "^2.2", "sonata-project/block-bundle": "^3.11", "sonata-project/core-bundle": "^3.9", "sonata-project/exporter": "^1.8", "symfony/asset": "^2.8 || ^3.2 || ^4.0", "symfony/config": "^2.8 || ^3.2 || ^4.0", "symfony/console": "^2.8 || ^3.2 || ^4.0", "symfony/dependency-injection": "^2.8 || ^3.2 || ^4.0", "symfony/event-dispatcher": "^2.8 || ^3.2 || ^4.0", "symfony/expression-language": "^2.8 || ^3.2 || ^4.0", "symfony/form": "^2.8 || ^3.2 || ^4.0", "symfony/framework-bundle": "^2.8 || ^3.2 || ^4.0", "symfony/http-foundation": "^2.8 || ^3.2 || ^4.0", "symfony/http-kernel": "^2.8 || ^3.2 || ^4.0", "symfony/options-resolver": "^2.8 || ^3.2 || ^4.0", "symfony/property-access": "^2.8 || ^3.2 || ^4.0", "symfony/routing": "^2.8 || ^3.2 || ^4.0", "symfony/security-acl": "^2.8 || ^3.0", "symfony/security-bundle": "^2.8 || ^3.2 || ^4.0", "symfony/security-core": "^2.8 || ^3.2 || ^4.0", "symfony/security-csrf": "^2.8 || ^3.2 || ^4.0", "symfony/templating": "^2.8 || ^3.2 || ^4.0", "symfony/translation": "^2.8 || ^3.2 || ^4.0", "symfony/twig-bridge": "^2.8 || ^3.2 || ^4.0", "symfony/twig-bundle": "^2.8 || ^3.2 || ^4.0", "symfony/validator": "^2.8 || ^3.2 || ^4.0", "twig/extensions": "^1.5", "twig/twig": "^1.34 || ^2.0" },"conflict": { "jms/di-extra-bundle": "<1.9", "sonata-project/media-bundle": "<3.7", "sonata-project/user-bundle": "<3.3" }, "require-dev": { "jms/di-extra-bundle": "^1.9", "jms/translation-bundle": "^1.4", "matthiasnoback/symfony-dependency-injection-test": "^1.1", "sensio/generator-bundle": "^3.1", "sonata-project/intl-bundle": "^2.4", "symfony/class-loader": "^2.8 || ^3.2", "symfony/filesystem": "^2.8 || ^3.2 || ^4.0", "symfony/phpunit-bridge": "^4.0", "symfony/yaml": "^2.8 || ^3.2 || ^4.0" }, "suggest": { "jms/di-extra-bundle": "Annotations for Admin definition", "jms/translation-bundle": "Extract message keys from Admins", "sensio/generator-bundle": "Add sonata:admin:generate command", "sonata-project/intl-bundle": "Add localized date and number into the list" }, "config": { "sort-packages": true }, "extra": { "branch-alias": { "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { "Sonata\\AdminBundle\\": "src/" } }, "autoload-dev": { "psr-4": { "Sonata\\AdminBundle\\Tests\\": "tests/" } } }
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

I think this is prob a problem of versioning/compatibillity right ?

@nmateo commented on GitHub (Oct 29, 2019): I think this is prob a problem of versioning/compatibillity right ?
Author
Owner

@Ocramius commented on GitHub (Oct 29, 2019):

No, probably something else. Have you tried reducing this to just the affected fields? What happens if you run orm:info with this entity and just the identifier plus the two boolean fields?

@Ocramius commented on GitHub (Oct 29, 2019): No, probably something else. Have you tried reducing this to just the affected fields? What happens if you run `orm:info` with this entity and just the identifier plus the two boolean fields?
Author
Owner

@lcobucci commented on GitHub (Oct 29, 2019):

composer show gives version 2.6.2 for this package (doctrine/orm) 👍
Your mapping seems okay (a bit convoluted, though).

I'd suggest updating to the latest ORM v2.6.4 (just to ensure you have the latest bugfixes - none related to this specifically) and to isolate the ORM behaviour from the rest - you have many things being integrated (various traits and usage of SF forms).

That isolation could be done by instantiating the object, persisting it (persist + flush), and fetching it from the DB (clear + find). This process would show if the ORM is the culprit here.

@lcobucci commented on GitHub (Oct 29, 2019): `composer show` gives version 2.6.2 for this package (`doctrine/orm`) :+1: Your mapping seems okay (a bit convoluted, though). I'd suggest updating to the latest ORM `v2.6.4` (just to ensure you have the latest bugfixes - none related to this specifically) and to isolate the ORM behaviour from the rest - you have many things being integrated (various traits and usage of SF forms). That isolation could be done by instantiating the object, persisting it (persist + flush), and fetching it from the DB (clear + find). This process would show if the ORM is the culprit here.
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

Updated to 2.6.4 Thanks @lcobucci. Could you show me a little bit how to instantiating the object, persisting it (persist + flush), and fetching it from the DB (clear + find) ?

@nmateo commented on GitHub (Oct 29, 2019): Updated to 2.6.4 Thanks @lcobucci. Could you show me a little bit how to instantiating the object, persisting it (persist + flush), and fetching it from the DB (clear + find) ?
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

Thanks @Ocramius. The php bin/console orm:info gives me nothing but an undefined command.

@nmateo commented on GitHub (Oct 29, 2019): Thanks @Ocramius. The php bin/console orm:info gives me nothing but an undefined command.
Author
Owner

@Ocramius commented on GitHub (Oct 29, 2019):

Maybe doctrine:info? No idea how this is done in symfony :-P

@Ocramius commented on GitHub (Oct 29, 2019): Maybe `doctrine:info`? No idea how this is done in symfony :-P
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

Thanks Ocramius, got this:
image

@nmateo commented on GitHub (Oct 29, 2019): Thanks Ocramius, got this: ![image](https://user-images.githubusercontent.com/9270970/67761783-48f13c00-fa44-11e9-8867-4ee6ba6c8d4c.png)
Author
Owner

@Ocramius commented on GitHub (Oct 29, 2019):

Maybe orm:mapping:describe (doctrine:mapping:describe in symfony context?) will help further.

Closing here meanwhile: as mentioned above, you have to isolate the issue by reducing the code until the minimum reproducible scenario, without the rest of the application code.

Once it is clear if/that it is an ORM bug, then please re-open with a more reduced example, maybe to be added to https://github.com/doctrine/doctrine2/tree/master/tests/Doctrine/Tests/ORM/Functional/Ticket

@Ocramius commented on GitHub (Oct 29, 2019): Maybe `orm:mapping:describe` (`doctrine:mapping:describe` in symfony context?) will help further. Closing here meanwhile: as mentioned above, you have to isolate the issue by reducing the code until the minimum reproducible scenario, without the rest of the application code. Once it is clear if/that it is an ORM bug, then please re-open with a more reduced example, maybe to be added to https://github.com/doctrine/doctrine2/tree/master/tests/Doctrine/Tests/ORM/Functional/Ticket
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

I can assure you it's a doctrine-orm issue since it tells me all is up to date and when i try to use my field suddenly it says it is not mapped, i manage to get a mapping description with: php bin/console sonata:core:dump-doctrine-metadata

image

@nmateo commented on GitHub (Oct 29, 2019): I can assure you it's a doctrine-orm issue since it tells me all is up to date and when i try to use my field suddenly it says it is not mapped, i manage to get a mapping description with: php bin/console sonata:core:dump-doctrine-metadata ![image](https://user-images.githubusercontent.com/9270970/67762892-b900c180-fa46-11e9-9af3-e2904feb499d.png)
Author
Owner

@Ocramius commented on GitHub (Oct 29, 2019):

And no caches involved?

@Ocramius commented on GitHub (Oct 29, 2019): And no caches involved?
Author
Owner

@lcobucci commented on GitHub (Oct 29, 2019):

And no caches involved?

Especially metadata cache.

@lcobucci commented on GitHub (Oct 29, 2019): > And no caches involved? Especially metadata cache.
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

I cleared all caches including doctrine metadata multiples times

@nmateo commented on GitHub (Oct 29, 2019): I cleared all caches including doctrine metadata multiples times
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

I got an error generating the dump of doctrine metadata here it is:

image

@nmateo commented on GitHub (Oct 29, 2019): I got an error generating the dump of doctrine metadata here it is: ![image](https://user-images.githubusercontent.com/9270970/67766949-eb62ec80-fa4f-11e9-9e29-17a2f2b04ed0.png)
Author
Owner

@nmateo commented on GitHub (Oct 29, 2019):

Thanks for the help it's now resolved after upgrading some dependencies and clearing caches it works great thanks again for the help!

@nmateo commented on GitHub (Oct 29, 2019): Thanks for the help it's now resolved after upgrading some dependencies and clearing caches it works great thanks again for the help!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#6336