Doctrine 1
  1. Doctrine 1
  2. DC-449

Duplicate entry integrity constraint error when updating Searchable record with indexed fields from a template

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.2.1
    • Fix Version/s: None
    • Component/s: None
    • Labels:
      None

      Description

      I have the following:

      <?php
      class JS_Page extends Doctrine_Record
      {
      	public function setTableDefinition()
      	{
      		$this->setTableName('page');
      		$this->hasColumns(array(
      			'id' => array(
      				'type'		=> 'integer',
      				'length'	=> 4,
      				'primary'	=> true,
      				'autoincrement'	=> true,
      			),
      			'content' => array(
      				'type'		=> 'array',
      				'length'	=> 65536,
      				'notnull'	=> true,
      				'default'	=> array(),
      			),
      		));
      	}
      
      	public function setUp()
      	{
      		$this->actAs(new JS_Template_Meta());
      		$this->actAs('Searchable', array(
      			'fields'	=> array('title', 'description', 'keywords'),
      			'tableName'	=> 'page_index',
      		));
      	}
      }
      
      class JS_Template_Meta extends Doctrine_Template
      {
      	public function setTableDefinition()
      	{
      		$this->hasColumns(array(
      			'title' => array(
      				'type'		=> 'string',
      				'length'	=> 255,
      				'notnull'	=> true,
      			),
      			'description' => array(
      				'type'		=> 'string',
      			),
      			'keywords' => array(
      				'type'		=> 'string',
      				'length'	=> 255,
      			),
      		));
      	}
      }
      

      When a Page record is updated I get this error:

      SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'application-title-0-3' for key 1
      

      If I only index fields from Page it works.

      I tracked this down to the code in Doctrine_Search that deletes the existing indexed data before re-indexing a record (I'm not using batchUpdate). For reasons I don't understand the DELETE query is not executing correctly before re-indexing, and so any unchanged data is being added to the index twice, causing the error.

      I managed to work around this by adding my own template and listener before Searchable, with a preSave event that deletes the index data:

      ...
      		$this->actAs(new JS_Template_Searchable());
      		$this->actAs('Searchable', array(
      			'fields'	=> array('title', 'description', 'keywords'),
      			'tableName'	=> 'page_index',
      		));
      ...
      
      class JS_Template_Searchable extends Doctrine_Template
      {
      	public function setTableDefinition()
      	{
      		$this->addListener(new JS_Template_Searchable_Listener());
      	}
      }
      
      class JS_Template_Searchable_Listener extends Doctrine_Record_Listener
      {
      	public function preSave(Doctrine_Event $event)
      	{
      		$invoker = $event->getInvoker();
      		$class = get_class($invoker) . 'Index';
      		$query = Doctrine_Query::create()
      			->delete()
      			->from("{$class} i")
      			->where("i.id = ?", $invoker['id'])
      			->execute();
      	}
      }
      

      Obviously that's an ugly hack, but it works.

        Activity

        There are no comments yet on this issue.

          People

          • Assignee:
            Jonathan H. Wage
            Reporter:
            Jack Sleight
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated: