[907] Ошибка при сохранении CActiveRecord

Предварительное обсуждение найденных ошибок перед отправкой их авторам фреймворка.

[907] Ошибка при сохранении CActiveRecord

Сообщение Stepan Selyuk » 2010.02.07, 16:17

Допустим есть модель, Pay. Таблица стандартная:

Код: Выделить всё

CREATE TABLE 
`ss_pays` (
  `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  `pay_sum` FLOAT(8,2) UNSIGNED NOT NULL DEFAULT '0.00' COMMENT 'Pay sum',
  `client_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
  `purchase_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
  `bill_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
  `partner_id` INT(10) UNSIGNED NOT NULL DEFAULT '0',
  `partner_id_from` INT(10) UNSIGNED NOT NULL DEFAULT '0',
  `reason_id` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
  `dcreate` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `missed` DECIMAL(1,0) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Pay is missed?',
  PRIMARY KEY (`id`)
)
 ENGINE=INNODB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8


Описание модели тоже стандартное. В моей реализации есть
конечно связи и т.д. но все это я отключал (переименовывал функции отвечающие за это). Баг сохраняется.

Итак где именно:

Если сделать так:

Код: Выделить всё

$p1 
= new Pay();
$p1->save();
 


То все нормально.
А если добавить еще хотя бы одну запись таким же образом, а потом сохранить объект $p1, то выскакивает исключение:

Код: Выделить всё

CDbCommand failed to execute the SQL statement
: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '23' for key 'PRIMARY'UPDATE 
`ss_pays` SET `pay_sum`=:yp0, `client_id`=:yp1, `purchase_id`=:yp2, `bill_id`=:yp3, `partner_id`=:yp4, `partner_id_from`=:yp5, `reason_id`=:yp6, 
`dcreate`=NOW(), `missed`=:yp7, `id`=:yp8 WHERE `ss_pays`.`id` IS NULL


т.е. для повторения ошибки нужно выполнить код:

Код: Выделить всё

$p1 
= new Pay();
$p1->save();
        
$p2 
= new Pay();
$p2->save();

$p1->bill_id = 1;
$p1->save();
 


Причем bill_id присваивать не обязательно. Ошибка и без этого.
Пока нашел решение как:

Код: Выделить всё

$p1 
= new Pay();
$p1->save();
        
$p2 
= new Pay();
$p2->save();

$p1 = Pay::model()->findByPk($p1->getPrimaryKey());
$p1->bill_id = 1;
$p1->save();
 


Видимо где-то что-то... в ядро лезть не стал.
Сначала невидимое, затем видимое. И так у всех программистов :)
Аватара пользователя
Stepan Selyuk
 
Сообщения: 67
Зарегистрирован: 2010.02.03, 05:51
Откуда: Vladivostok

Re: Ошибка при сохранении CActiveRecord

Сообщение Sam Dark » 2010.02.07, 17:10

Когда вы сохраняете $p1, в $p1 записывается id. Повтороное сохранение с тем же id вызывает ошибку. Это нормально.
Аватара пользователя
Sam Dark
Администратор
 
Сообщения: 1676
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж

Re: Ошибка при сохранении CActiveRecord

Сообщение Ekstazi » 2010.02.07, 18:22

Sam Dark писал(а):Когда вы сохраняете $p1, в $p1 записывается id. Повтороное сохранение с тем же id вызывает ошибку. Это нормально.

Ну почему же ?
Код: Выделить всё
$p1->isNewRecord=false;
$p1->save(); 

И проблема решена.
Ekstazi
 
Сообщения: 441
Зарегистрирован: 2009.08.20, 22:54

Re: Ошибка при сохранении CActiveRecord

Сообщение Stepan Selyuk » 2010.02.08, 08:08

Ekstazi писал(а):
Sam Dark писал(а):Когда вы сохраняете $p1, в $p1 записывается id. Повтороное сохранение с тем же id вызывает ошибку. Это нормально.

Ну почему же ?
Код: Выделить всё
$p1->isNewRecord=false;
$p1->save(); 

И проблема решена.


Нет, так проблема не решается :) Так как это свойство уже после первого сохранения выставлено в false.
По логике вещей если объекту уже присвоен ID, и вызывается повторное сохранение, то он просто должен сохранить значение в базе, используя primary key.

Я написал этот пост к тому, что код:

Код: Выделить всё

$p1 
= new Pay();
$p1->save();
$p1->bill_id 1;
$p1->save();
 


Работает. Как и должно.
Но если вставляется между сохранениями другая строка, по появляется ошибка.
Сначала невидимое, затем видимое. И так у всех программистов :)
Аватара пользователя
Stepan Selyuk
 
Сообщения: 67
Зарегистрирован: 2010.02.03, 05:51
Откуда: Vladivostok

Re: Ошибка при сохранении CActiveRecord

Сообщение Ekstazi » 2010.02.08, 12:21

Надо бы это дело в баг репорты отписать и разобраться почему так происходит.
Ekstazi
 
Сообщения: 441
Зарегистрирован: 2009.08.20, 22:54

Re: Ошибка при сохранении CActiveRecord

Сообщение Sam Dark » 2010.02.08, 14:05

На модели без связей с двумя полями в таблице: id и title воспроизводится?
Аватара пользователя
Sam Dark
Администратор
 
Сообщения: 1676
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж

Re: Ошибка при сохранении CActiveRecord

Сообщение Stepan Selyuk » 2010.02.08, 15:36

Да, воспроизводится.

Код: Выделить всё

CREATE TABLE 
`ss_tests` (
  `
idINT(10UNSIGNED NOT NULL AUTO_INCREMENT,
  `
titleVARCHAR(50) DEFAULT NULL,
  
PRIMARY KEY (`id`)
ENGINE=INNODB AUTO_INCREMENT=DEFAULT CHARSET=utf8


Код: Выделить всё

$t1 
= new Test();
$t1->title 'a';
$t1->save();
            
$t2 = new Test();
$t2->title 'b';
$t2->save();
            
$t1->save();
 


Модель сгенерирована через shell.

Exception:
Код: Выделить всё

CDbCommand failed to execute the SQL statement
SQLSTATE[23000]: Integrity constraint violation1062 Duplicate entry '1' for key 'PRIMARY'UPDATE `ss_tests
SET `title`=:yp0, `id`=:yp1 WHERE `ss_tests`.`idIS NULL
Сначала невидимое, затем видимое. И так у всех программистов :)
Аватара пользователя
Stepan Selyuk
 
Сообщения: 67
Зарегистрирован: 2010.02.03, 05:51
Откуда: Vladivostok

Re: Ошибка при сохранении CActiveRecord

Сообщение Sam Dark » 2010.02.08, 15:53

Аватара пользователя
Sam Dark
Администратор
 
Сообщения: 1676
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж

Re: [907] Ошибка при сохранении CActiveRecord

Сообщение Stepan Selyuk » 2010.02.08, 17:04

Cамое обидное в этом случае, вот что:

Если сделать вместо второго Save(),
Код: Выделить всё
$model->saveAttributes(array ('title')) 

То даже исключением не ловится (всмысле не вызывает исключение и возвращает true).

Поэтому это может вызвать просто ошибку в программе.. вот сейчас сижу проверяю код на этот глюк.

Исполняет примерно такой код (но думаю они это пофиксили, так как в обоих случаях передается WHERE id IS NULL)
Код: Выделить всё

Executing SQL
: UPDATE `ss_nodes` SET `children`=:yp0, `ppcount`=:yp1, `unblock_deep_percent`=:yp2 WHERE `ss_nodes`.`id` IS NULL. 
Bind with parameter 
:yp0='1', :yp1=1, :yp2='0'
 


Кстати, я разместил (в авторских рецептах) свой вариант поведения для вложенных деревьев (переделанный с оригинального класса CDBTree). Прошу затестить, можно допилить до нормального варианта.
Сначала невидимое, затем видимое. И так у всех программистов :)
Аватара пользователя
Stepan Selyuk
 
Сообщения: 67
Зарегистрирован: 2010.02.03, 05:51
Откуда: Vladivostok

Re: [907] Ошибка при сохранении CActiveRecord

Сообщение Sam Dark » 2010.02.08, 17:07

Вроде фикснули.
Аватара пользователя
Sam Dark
Администратор
 
Сообщения: 1676
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж

След.

Вернуться в Баг-репорты

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1