Doctrine2 findOneBy返回错误的结果

时间:2016-06-03 22:28:58

标签: mysql symfony doctrine-orm

我正在使用Symfony2.3和以下版本的doctrine组件(作曲家show -i | grep doctrine)处理遗留项目:

doctrine/annotations                     v1.1.2 
doctrine/cache                           v1.2.0 
doctrine/collections                     dev-master bcb5377 
doctrine/common                          2.4.x-dev c94d6ff 
doctrine/data-fixtures                   dev-master 8ffac1c 
doctrine/dbal                            2.3.x-dev 59c310b 
doctrine/doctrine-bundle                 dev-master a41322d
doctrine/doctrine-fixtures-bundle        dev-master 3caec48
doctrine/doctrine-migrations-bundle      dev-master 1a7f58d 
doctrine/inflector                       dev-master 8b4b3cc
doctrine/lexer                           dev-master bc0e1f0
doctrine/migrations                      dev-master e960224 
doctrine/orm                             2.3.x-dev 66d8b43

我必须实现一个简单的数据库缓存系统。

我有一个存储表和一个服务类来访问它。 表模式如下:

CREATE TABLE `mlp_api_storage` (
    `id` TINYINT(4) NOT NULL AUTO_INCREMENT,
    `key` VARCHAR(250) NOT NULL,
    `value` TEXT NOT NULL,
    `is_serialized` TINYINT(4) NOT NULL,
    `created` DATETIME NOT NULL,
    `ttl` INT(11) NULL DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE INDEX `Index 2` (`key`)
)

我遇到的一个大问题是,当我尝试检索一个值时,我得到了错误的结果。 我正在跟踪日志文件,我可以看到正在使用正确的键值执行的查询,如果我直接在MySQL中运行,我将获得我期望的值,但不会使用doctrine。

以下是存储服务的相关代码:

/**
 * @param string $key
 * @param string $value
 * @param mixed $ttl
 * @return self
 */
public function set($key, $value, $ttl = null)
{
    $em     = $this->getEntityManager();
    $store  = $this->fetchEntity($key);
    $update = true;

    if (!$store) {
        $update = false;
        $store  = new Storage();
    }

    $store->setKey($key);

    if (is_object($value) || is_array($value)) {
        $value = serialize($value);
        $store->setIsSerialized(true);
    } else {
        $store->setIsSerialized(false);
    }

    $store->setValue($value);
    $store->setTtl($this->calculateTTL($ttl));
    $store->setCreated(new \DateTime());

    if ($update) {
        $em->merge($store);
    } else {
        $em->persist($store);
    }

    $em->flush($store);

    return $this;
}

       /**
         * @param string $key
         * @param mixed $default
         * @return string|null
         */
        public function fetch($key, $default = null)
        {
            $res = $this->fetchEntity($key);

            if ($res) {
                if ($this->isValidStorage($res)) {
                    $value = $res->getValue();

                    if ($res->getIsSerialized()) {
                        $value = unserialize($value);
                    }

                    return $value;
                }

                $this->remove($res);
            }

            if ($default) {
                $res = (is_callable($default)) ? $default($this) : $default;
            } else {
                $res = null;
            }

            return $res;
        }

        /**
         * @param string $key
         * @return Storage
         */
        private function fetchEntity($key)
        {
            /* @var $res Storage */
            $res = $this->getEntityManager()
                ->getRepository(Storage::class)
                ->findOneBy(['key' => $key]);

            if ($res) {
                return $res;
            }

            return null;
        }

所以使用调试器(和mysql日志)我可以看到一切都很好,直到行: - > findOneBy([' key' => $ key]);

这将使用具有不同键和值的实体进行设置。

我设置了一个小例子:

$storage->set('test', '1111111111111111111');
$storage->set('test2', '22222222222222222222');
var_dump($storage->fetch('test'));
var_dump($storage->fetch('test2'));

这是回归:

  

string' 1111111111111111111' (长度= 19)

     

string' 1111111111111111111' (长度= 19)

以下是表格中的内容:

enter image description here

这是mysql日志输出:

66 Query     SELECT t0.`key` AS key1, t0.value AS value2, t0.is_serialized AS is_serialized3, t0.created AS created4, t0.ttl AS ttl5, t0.id AS id6 FROM storage t0 WHERE t0.`key` = 'test' LIMIT 1
66 Query     SELECT t0.`key` AS key1, t0.value AS value2, t0.is_serialized AS is_serialized3, t0.created AS created4, t0.ttl AS ttl5, t0.id AS id6 FROM storage t0 WHERE t0.`key` = 'test2' LIMIT 1

我对doctrine2做错了吗?我正在更新实体而不是删除,因为doctrine会在删除之前尝试插入。

谢谢!

更新:

这是实体代码

namespace PitchBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Storage
 *
 * @ORM\Table(name="storage")
 * @ORM\Entity
 */
class Storage
{
    /**
     * @var string
     *
     * @ORM\Column(name="`key`", type="string", length=250, nullable=false)
     */
    private $key;

    /**
     * @var string
     *
     * @ORM\Column(name="value", type="text", nullable=false)
     */
    private $value;

    /**
     * @var boolean
     *
     * @ORM\Column(name="is_serialized", type="boolean", nullable=false)
     */
    private $isSerialized;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="created", type="datetime", nullable=false)
     */
    private $created;

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

    /**
     * @var boolean
     *
     * @ORM\Column(name="id", type="boolean")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * Set key
     *
     * @param string $key
     * @return Storage
     */
    public function setKey($key)
    {
        $this->key = $key;

        return $this;
    }

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

    /**
     * Set value
     *
     * @param string $value
     * @return Storage
     */
    public function setValue($value)
    {
        $this->value = $value;

        return $this;
    }

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

    /**
     * Set isSerialized
     *
     * @param boolean $isSerialized
     * @return Storage
     */
    public function setIsSerialized($isSerialized)
    {
        $this->isSerialized = $isSerialized;

        return $this;
    }

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

    /**
     * Set created
     *
     * @param \DateTime $created
     * @return Storage
     */
    public function setCreated($created)
    {
        $this->created = $created;

        return $this;
    }

    /**
     * Get created
     *
     * @return \DateTime
     */
    public function getCreated()
    {
        return $this->created;
    }

    /**
     * Set ttl
     *
     * @param integer $ttl
     * @return Storage
     */
    public function setTtl($ttl)
    {
        $this->ttl = $ttl;

        return $this;
    }

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

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

1 个答案:

答案 0 :(得分:1)

您的实体id注释中存在错误。目前它是:

 * @ORM\Column(name="id", type="boolean")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")

但它应该是

 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")