onPHP / onphp-framework

onPHP is the mature GPL'ed multi-purpose object-oriented PHP framework.
85 stars 52 forks source link

Ошибка сохранения коллекций #230

Open bassta opened 9 years ago

bassta commented 9 years ago

Столкнулся с непонятным поведением при сохранении коллекций.

Есть 2 тестовых класса:

        <class name="Bar" type="final">
            <properties>
                <identifier />
                <property name="foos" type="Foo" relation="OneToMany" />
            </properties>
            <pattern name="StraightMapping" />
        </class>

        <class name="Foo" type="final">
            <properties>
                <identifier />
                <property name="bar" type="Bar" relation="OneToOne" />
            </properties>
            <pattern name="StraightMapping" />
        </class>

И такой вот тест:

    $bar = Bar::create();
    $bar = $bar->dao()->add($bar);

    $foo = Foo::create();
    $foo->dao()->add($foo);

    $bar->getFoos()->
        fetch()->
        setList(array($foo))->
        save();

По идее, при выполнении метода save, должно произойти обновление записей в таблице foo. Но на самом деле происходит добавление новых записей. Причем поле связи bar_id, которое должно содержать id записи из таблицы bar остается пустым. Т.е. $bar->getFoos()->getList() вернет пустой список.

Вот что пишет в лог Postgres:

select nextval('bar_id') as seq
INSERT INTO "bar" ("id") VALUES ('17')
select nextval('foo_id') as seq
INSERT INTO "foo" ("id", "bar_id") VALUES ('27', NULL)
SELECT "foo"."id", "foo"."bar_id" FROM "foo" WHERE ("foo"."bar_id" = '17')
begin;
select nextval('foo_id') as seq
INSERT INTO "foo" ("id", "bar_id") VALUES ('28', NULL)
commit;

А вот что пишет в лог MySql:

INSERT INTO `bar` (`id`) VALUES (NULL)
INSERT INTO `foo` (`id`, `bar_id`) VALUES (NULL, NULL)
SELECT `foo`.`id`, `foo`.`bar_id` FROM `foo` WHERE (`foo`.`bar_id` = '19')
begin
INSERT INTO `foo` (`id`, `bar_id`) VALUES (NULL, NULL)
commit

Пробовал в ветках 1.0, 1.1, master - везде одинаковое поведение.

crazedr0m commented 9 years ago

а mergeList() вместо setList() не приведет к нужному результату?

bassta commented 9 years ago

Нет, не приведет.

При связях ManyToMany, работает все правильно, а OneToMany нет. Насколько я понял, там логика подразумевается такая: элемент коллекции (Foo) не может существовать вне коллекции (Bar). Поэтому запрос insert, а не update идет в бд. Но в любом случае поле связи пустое в запросе.