Doctrine 2 - ORM
  1. Doctrine 2 - ORM
  2. DDC-2012

Inserting a new entity with a custom mapping type does not call convertToDatabaseValueSQL() when using InheritanceType("JOINED")

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 2.2.3
    • Fix Version/s: 2.3.1
    • Component/s: Mapping Drivers
    • Security Level: All
    • Labels:
      None
    • Environment:
      PHP

      Description

      When using class type inheritance - @InheritanceType("JOINED") and inserting new entity with a custom mapping type, custom type method convertToDatabaseValueSQL() is never called.

      Here is sample class mapping:

      Unable to find source-code formatter for language: php. Available languages are: actionscript, html, java, javascript, none, sql, xhtml, xml
       
      /**
       * @Table(name="item")
       * @Entity
       * @InheritanceType("JOINED")
       * @DiscriminatorColumn(name="type_id", type="smallint")
       * @DiscriminatorMap({1 = "ItemPerson"})
       */
      class Item {
      
      	/**
      	 * @Column(name="tsv", type="tsvector", nullable=true)
      	 */
      	protected $tsv;
      }
      
      /**
       * @Table(name="item_person")
       * @Entity
       */
      class ItemPerson extends Item
      {
      }
      
      

      I am using the same custom TsvectorType with simple entities and even Mapped Superclasses and it works perfectly, however on InheritanceType("JOINED") method convertToDatabaseValueSQL() is never called :/
      Hope someone knows how to fix this.
      Thank you.

      1. DDC2012Test.php
        4 kB
        Fabio B. Silva
      2. DDC2012Test.php
        4 kB
        Kaspars Sproģis

        Activity

        Hide
        Fabio B. Silva added a comment - - edited

        Hi Kaspars,

        I can't reproduce,
        Could you change the added testcase and try to make it fails ?

        Thanks

        Show
        Fabio B. Silva added a comment - - edited Hi Kaspars, I can't reproduce, Could you change the added testcase and try to make it fails ? Thanks
        Hide
        Kaspars Sproģis added a comment - - edited

        @Fabio thanks for looking into my problem
        I attached test where you can detect the problem.

        It was quite strange, all i did was changed column that uses custom type to array and some minimal convertToDatabaseValue and convertToDatabaseValueSQL logic and convertToDatabaseValueSQL was never called.

        One more thing i noticed, this bug only appears on persist and not on merge.

        Thanks

        Show
        Kaspars Sproģis added a comment - - edited @Fabio thanks for looking into my problem I attached test where you can detect the problem. It was quite strange, all i did was changed column that uses custom type to array and some minimal convertToDatabaseValue and convertToDatabaseValueSQL logic and convertToDatabaseValueSQL was never called. One more thing i noticed, this bug only appears on persist and not on merge. Thanks
        Hide
        Fabio B. Silva added a comment -

        Thanks Kaspars

        But sorry, I dont get your use case.

        Notice that convertToDatabaseValueSQL is called just when using queries to find a object by a especific columns which is your mapping type.

        http://docs.doctrine-project.org/en/2.1/cookbook/advanced-field-value-conversion-using-custom-mapping-types.html#the-mapping-type

        Show
        Fabio B. Silva added a comment - Thanks Kaspars But sorry, I dont get your use case. Notice that convertToDatabaseValueSQL is called just when using queries to find a object by a especific columns which is your mapping type. http://docs.doctrine-project.org/en/2.1/cookbook/advanced-field-value-conversion-using-custom-mapping-types.html#the-mapping-type
        Hide
        Kaspars Sproģis added a comment - - edited

        I am using PostgreSQL tsvector data type for full text search.

        Here is my tsvector custom data type class:
        https://gist.github.com/3129096

        The only way to update this field in postgresql is to use postgresql function to_tsvector('some text').
        And everything works fine, if i persist simple entity, this method transforms insert query as needed:

        public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
        {
        	return sprintf('to_tsvector(%s)', $sqlExpr);
        }
        

        But when i use inheritance, then by some reason convertToDatabaseValueSQL method is not called and tsv field is updated with simple text as returned by convertToDatabaseValue() method.
        I modified the Ticket Test so that you can see exact moment of when it is not called, which is exactly my problem.

        Here is the result after persisting (for persist it failed)

        $person = new ItemPerson();
        $person->setName('some words for test');
        $em->persist($person);
        $em->flush();
        
        DB Result:
        Name                | Tsv
        --------------------|------------------------------------
        some words for test | 'for' 'some' 'test' 'words'
        

        Here is the result after second time update (now by tsv format you can see it worked):

        $person->setName('some more words for test');
        $em->flush();
        
        DB Result:
        Name                | Tsv
        --------------------|------------------------------------
        some words for test | 'test':5 'word':3
        
        Show
        Kaspars Sproģis added a comment - - edited I am using PostgreSQL tsvector data type for full text search. Here is my tsvector custom data type class: https://gist.github.com/3129096 The only way to update this field in postgresql is to use postgresql function to_tsvector('some text'). And everything works fine, if i persist simple entity, this method transforms insert query as needed: public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform) { return sprintf('to_tsvector(%s)', $sqlExpr); } But when i use inheritance, then by some reason convertToDatabaseValueSQL method is not called and tsv field is updated with simple text as returned by convertToDatabaseValue() method. I modified the Ticket Test so that you can see exact moment of when it is not called, which is exactly my problem. Here is the result after persisting (for persist it failed) $person = new ItemPerson(); $person->setName('some words for test'); $em->persist($person); $em->flush(); DB Result: Name | Tsv --------------------|------------------------------------ some words for test | ' for ' 'some' 'test' 'words' Here is the result after second time update (now by tsv format you can see it worked): $person->setName('some more words for test'); $em->flush(); DB Result: Name | Tsv --------------------|------------------------------------ some words for test | 'test':5 'word':3
        Hide
        Fabio B. Silva added a comment -

        Thanks Kaspars

        Now i saw the problem

        Writing a patch ...

        Show
        Fabio B. Silva added a comment - Thanks Kaspars Now i saw the problem Writing a patch ...
        Hide
        Kaspars Sproģis added a comment -

        Just tested fixed version and everything works perfectly now.
        Thank you!

        Show
        Kaspars Sproģis added a comment - Just tested fixed version and everything works perfectly now. Thank you!
        Show
        Fabio B. Silva added a comment - Fixed by : https://github.com/doctrine/doctrine2/commit/91caff1d8965c20b72d5fdd04ffadf3ab063c1ba

          People

          • Assignee:
            Fabio B. Silva
            Reporter:
            Kaspars Sproģis
          • Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: