Skip to content

save() silently skips UPDATE for entities inserted in the same request #36

@michielgerritsen

Description

@michielgerritsen

Description

When an entity is created with new, inserted via save(), and then mutated and passed to save() again in the same request, the UPDATE is silently skipped and no exception is thrown.

Root cause:
Repository::update() calls EntityHydrator::getDirtyProperties() to determine which columns changed. That method compares current values against an $originalValues map that is only populated by
EntityHydrator::hydrate() — i.e. when an entity is read from the database.

When save() performs an INSERT, it sets the primary key via reflection but never registers the entity's state in $originalValues. The map stays empty, getDirtyProperties() returns [], and update() returns early without executing any SQL.

Suggested fix:

After the INSERT query completes, call a hydrator method (e.g. registerOriginalValues($entity, $metadata)) that snapshots the entity's current property values into $originalValues — mirroring what hydrate() does when loading from the database.

Workaround:

Re-fetch the entity from the database after inserting before applying further changes:

$repository->save($entity);
$entity = $repository->find($entity->id); // hydrates $originalValues correctly                                                                                                                           
$entity->status = 'completed';                                                                                                                                                                            
$repository->save($entity); // UPDATE works as expected

Steps to Reproduce

$entity = new Transaction();
$entity->status = 'pending';                                                                                                                                                                              
// ... set required fields
                                                                                                                                                                                                        
$repository->save($entity); // INSERT — $entity->id is now set                                                                                                                                            

$entity->status = 'completed';                                                                                                                                                                            
$repository->save($entity); // Expected: UPDATE — Actual: no-op 

Expected Behavior

After a successful INSERT, the entity's current state should be registered as its original values so that subsequent save() calls correctly detect and persist changes.

Actual Behavior

The new values aren't persisted to the database.

Package

database

PHP Version

8.5

Marko Version

0.3.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions