简体   繁体   English

Doctrine2 findOneBy返回错误的结果

[英]Doctrine2 findOneBy returning wrong result

I am working on a legacy project using Symfony2.3 and the following versions of doctrine components (composer show -i | grep doctrine): 我正在使用Symfony2.3和以下版本的主义组件(composer show -i | grep主义)进行旧项目:

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

I had to implement a simple db cache system. 我必须实现一个简单的数据库缓存系统。

I have a storage table and a service class to access it. 我有一个存储表和一个访问它的服务类。 The table schema is as follows: 表模式如下:

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`)
)

The big issue I am having with this is one some occasions when I try to retrieve a value I get the wrong result. 我遇到的最大问题是,在某些情况下,当我尝试检索值时,得到错误的结果。 I am tailing the log file and I can see the query being executed with the correct key value and if I run that directly in MySQL I will get the value I expect but not with doctrine. 我正在跟踪日志文件,可以看到正在使用正确的键值执行查询,如果直接在MySQL中运行该查询,则将获得我期望的值,但不能使用教义。

Here is the relevant code of the storage service: 以下是存储服务的相关代码:

/**
 * @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;
        }

So using the debugger (and mysql log) I can see that everything is fine up until the line with : ->findOneBy(['key' => $key]); 因此,使用调试器(和mysql日志),我可以看到一切正常,直到与以下行:-> findOneBy(['key'=> $ key]);

This will be set with an entity with a different key and value. 这将使用具有不同键和值的实体进行设置。

I have setup a small example: 我设置了一个小例子:

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

This is returning: 这是返回:

string '1111111111111111111' (length=19) 字符串'1111111111111111111'(长度= 19)

string '1111111111111111111' (length=19) 字符串'1111111111111111111'(长度= 19)

Here is what is in the table: 这是表中的内容:

在此处输入图片说明

Here is the mysql log output: 这是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

Am I doing something wrong with doctrine2? 我对doctrine2做错了吗? I am updating the entity instead of deleting because doctrine will try to insert before deleting. 我要更新实体而不是删除实体,因为原则会在删除之前尝试插入。

Thanks! 谢谢!

UPDATE: 更新:

Here is the entity code 这是实体代码

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;
    }
}

You have an error in your entity id annotation. 您的实体id注释中存在错误。 Currently it is: 当前是:

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

but it should be 但这应该是

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM