YetOrm – získání id nově vytvořené entity
- chikeet
- Člen | 160
Zdravím,
používám YetOrm, jako id mám UUID4 a potřebuju získat id právě
vloženého řádku. Z entity ho po persistu nevytáhnu, protože
The value of column 'id' not set.
Přes Nette\Database::getInsertId
taky ne, protože
Error in transaction: SQLSTATE[55000]: Object not in prerequisite state: 7 ERROR: lastval is not yet defined in this session
.
Zkoušela jsem s transakcí i bez transakce, problém stejný. Jak na to?
- David Matějka
- Moderator | 6445
ohledně unikátnosti uuid bych si nedělal starosti :) If every person on the planet generates a new UUID4 every second, we’d expect a collision to occur after about 10 years.
a pokud by se tak opravdu velkou náhodou stalo, tak zkrátka selže unique constraint.
jednou z výhod uuid je právě to, že se nemusejí generovat databází, ale mohu je vygenerovat v aplikaci
- uestla
- Backer | 799
@chikeet To je zvláštní, jakou verzi YetORM používáš? Vložený řádek by se měl po persistu nastavovat:
- chikeet
- Člen | 160
uestla napsal(a):
@chikeet To je zvláštní, jakou verzi YetORM používáš? Vložený řádek by se měl po persistu nastavovat:
Používám 10.1.2. Měla jsem ve svém BaseRepository::persist
nějaké legacy zbytečnosti z jiného projektu, takže jsem to maximálně
zjednodušila podle Repository::persist
. Háže mi to ale
Error in transaction: Insert did not return instance of Nette\\Database\\IRow. Does table \"example\" have primary key defined? If so, try cleaning cache.
PK mám definovaný, cache promazanou.
Můj persist teď vypadá takto:
public function persist(YetORM\Entity $entity, ?User $updatedByUser = null): bool
{
/* events before persist */
$isUpdate = $entity->toRecord()->hasRow();
if ($isUpdate) {
$this->onBeforeUpdate($entity, $updatedByUser);
} else {
$this->onBeforeInsert($entity);
}
$this->checkEntity($entity);
$result = $this->transaction(function () use ($entity) {
$record = $entity->toRecord();
if ($record->hasRow()) {
return $record->update();
}
$inserted = $this->getTable()
->insert($record->getModified());
if (!$inserted instanceof \Nette\Database\IRow) {
throw new YetOrm\Exception\InvalidStateException('Insert did not return instance of ' . \Nette\Database\IRow::class . '. '
. 'Does table "' . $this->getTableName() . '" have primary key defined? If so, try cleaning cache.');
}
$record->setRow($inserted);
return TRUE;
});
/* events after persist */
if ($isUpdate) {
$this->onAfterUpdate($entity, $updatedByUser);
} else {
$this->onAfterInsert($entity);
}
return $result;
}
Nějaký nápad, čím to může být? Když to nepůjde, tak budu holt generovat idčka v PHP, ale v db by mi to bylo milejší vzhledem k tomu, že už to mám všude definované.
- uestla
- Backer | 799
@chikeet Insert na úrovni Selection
je poměrně
robustní, co se detekce hodnoty primárního klíče týče:
https://github.com/…election.php#L863
Je to sice hrabání ve vnitřnostech, ale možná to je cesta.
- chikeet
- Člen | 160
uestla napsal(a):
@chikeet Insert na úrovni
Selection
je poměrně robustní, co se detekce hodnoty primárního klíče týče:
https://github.com/…election.php#L863Je to sice hrabání ve vnitřnostech, ale možná to je cesta.
Nakonec vyřešeno generováním ID v PHP – cesta nejmenšího odporu a i jinak celkem smysluplná.