whether an error is thrown depends on the version of the database. Not supplying field data and creating a record is fine without strict mode
Serious issue where Save() returns true but record is not persisted to the database
Hi All, I have come across and tested a serious issue where save() returns true but does not persist the record to the database. I had some questions on this.
The error in question happened because a new field added to the data model had erroneously not been assigned a default value.
However with this in mind, the expected behaviour of the save() method would be to return false in this case. But it returned true. The same behaviour was observered using firstOrCreate() and firstOrNew() also which in I realise are essentially just convenience wrappers for save() so it makes sense that they returned the same value.
I see this as an extremely serious error. This was being run within a transaction. Had it not been for me subsequently trying to attach some relations to the created model, then no exception would have been thrown and the transaction would have committed and returned true while it had silently failed.
DB::beginTransaction();
try{
$taxonRecord = new TaxonRecord($attributes);
$recordSource = $taxonRecord->recordSource;
$taxonRecord->record_source_name = $recordSource->name;
DB::enableQueryLog();
if(!$taxonRecord->save()){//I specifically put in this if statement to try and make it catch the error but it still does not
Log::error($taxonRecord);
throw new \Exception('Taxon record was not saved.');
}
Log::info(DB::getQueryLog());//Query log shows the query and bindings. When run in heidiSql I discovered the miss
//This fails since there is now an integrity constraint since the TaxonRecord was not actually perisited. We should not have reached this point!!
$customAttributes = $recordSource->customAttributes;
foreach($customAttributes as $customAttribute){
$customAttributeValue = array_get($attributes, $customAttribute->name, null);//Find the attribute in the array, set to null if it does not exist.
if( !empty($customAttributeValue) ){
$taxonRecord->customAttributes()->attach([ $customAttribute->custom_attribute_id => ['value' => $customAttributeValue] ]);
}
}
DB::commit();
return $taxonRecord;
} catch (\Exception $e){
DB::rollBack();
Log::error($e);
return false;
}
Your thought's please gentlemen.
I got to the bottom of this today. This was a bug with MariaDB which has been fixed in 10.1.22. See here for details https://jira.mariadb.org/browse/MDEV-11842.
Basically HeidiSQL could see that the row had not been added and threw its own error but MariaDB did not throw an actual error which is why save() could not ascertain that anything was amiss. Hopefully it will help someone else.
Thanks.
Please or to participate in this conversation.