Skip to content
This repository

[Concrete Inheritance] Parent class doesn't save collections when save is called from child class #586

Open
jlorente opened this Issue · 6 comments

3 participants

Pepe Jérémie Augustin pimpreneil
Pepe

The problem is that parent classes doesn't save related objects defined by child classes. So, if you have a table related to parent table, methods like ->add{Related}() or ->set{Relateds}() used from child classes doesn't save these collections on the Database on ->save().
I've solved this problem overriding the creation of method getSyncParent() on the generator and adding the proper set{Collections} to it.
I don't know if this is a bug or it works this way for some reason.

Jérémie Augustin
Collaborator

@jlorente if child class call parent class save it should save collections otherwise it could be normal :)

Pepe

Child class doesn't save parent collections, because it doesn't synchronize his stored collections with the parent class before saving it. I think child classes should have all the functionality of parent classes including their collections, behaviors, etc.

Jérémie Augustin
Collaborator

could you provide a schema ?

Pepe
<?xml version="1.0" encoding="UTF-8"?>
<database package= "parentTest" name="parent_test" defaultIdMethod="native">    
    <table name="user" phpName="User">
        <column name= "user_id" phpName= "UserId" primaryKey= "true" required= "true" type= "INTEGER" autoIncrement= "true"></column>
        <column name= "name" phpName= "Name" required= "true" type="VARCHAR"></column>
    </table>
    <table name="resource" phpName="Resource">
        <column name= "resource_id" phpName= "ResourceId" primaryKey= "true" required= "true" type= "INTEGER" autoIncrement= "true"></column>
        <column name= "resource_size" phpName= "ResourceSize" required= "true" type= "REAL"></column>
        <column name= "name" phpName= "SingularName" required= "true" type= "VARCHAR" size= "255"></column>
    </table>
    <table name="image" phpName="Image">
        <behavior name="concrete_inheritance">
                <parameter name="extends" value="resource" />
        </behavior> 
        <column name= "height" phpName= "Height" required= "true" type="REAL"></column>
        <column name= "width" phpName= "Width" required= "true" type="REAL"></column>
    </table>
    <table name="podcast" phpName="Podcast">
        <behavior name="concrete_inheritance">
                <parameter name="extends" value="resource" />
        </behavior>
        <column name= "bit_rate" phpName= "BitRate" required= "true" type="INTEGER"></column>
    </table>
    <table name="user_resources" phpName="UserResource">
        <column name= "user_id" phpName= "UserId" required= "true" type= "INTEGER" primaryKey= "true"></column>
        <column name= "resource_id" phpName= "ResourceId" required= "true" type= "INTEGER" primaryKey= "true"></column>
        <foreign-key foreignTable="resource" name="RT_UserResource_ResourceId" onDelete="CASCADE" onUpdate="CASCADE"  >
            <reference local="resource_id" foreign="resource_id"/>
        </foreign-key>
        <foreign-key foreignTable="user" name="RT_UserResource_UserId" onDelete="CASCADE" onUpdate="CASCADE"  >
            <reference local="user_id" foreign="user_id"/>
        </foreign-key>
        <index name="RT_UserResource_UserId">
                    <index-column name="user_id"/>
        </index>
        <index name="RT_UserResource_ResourceId">
               <index-column name="resource_id"/>
        </index>
    </table>
</database>

In the above example, class User has a n-n relation with Resource and Image and Podcast are child classes of Resource.

Consider thar userId 1 and 2 exists;

$image = new Image();
$image->setResourceSize(1000);
$image->setName('TestImage');
$image->setHeight(100);
$image->setWitdth(100);

$userResourceA = new UserResource();
$userResourceA->setUserId(1);
$image->addUserResource($userResourceA);

$userResourceB = new UserResource();
$userResourceB->setUserId(2);
$image->addUserResource($userResourceB);
$image->save();

In this example, image instance doesn't save the relation between the parent class Resource and User. The code doesn't fail, but the collection of UserResource objects is ignored.

Jérémie Augustin
Collaborator

@jlorente I got the same issue today, I can confirm the bug. I will look at it.
affected versions at least 1.6.9 and 1.7.0.

Maybe it work this way because of other issue, but we should provide an easy way to save one to many and many to many relations related to parent object

pimpreneil

I have encountered the same issue when binding a form type on a concrete inherited object. I came out with two temporary (ugly) workarounds:

  • Manually create the middle-table's entries in my model's preSave lifecycle callback.
  • Bind the request on the parent object after the child's save call. Any clue about where this issue could come from?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.