Inserting Data (append)
append is ObjectQuel's bulk, set-based insert statement — QUEL's insert verb, run directly against the database through the same EntityManager::executeQuery() entry point as retrieve and the DDL statements on Creating, Altering & Destroying Tables & Indexes. It bypasses the identity map and change tracking entirely. If you need entity lifecycle behavior — cascades, events, per-object optimistic-lock exceptions — use persist()/flush() instead. See also replace, delete, and upsert.
Inserting Data with append
Assign each property a value using attr = value pairs:
$entityManager->executeQuery("
range of u is App\\Entity\\UserEntity
append to u (username = :username, password = :password, banned = false)
", ['username' => 'alice', 'password' => 'secret']);
Auto-generated primary keys (identity, sequence, UUID) are generated automatically, as with
persist(); provide one only to override it. Other columns must be supplied unless nullable
or defined with @Orm\Column(default=...). Omitted nullable columns are excluded from the
INSERT, letting the database apply DEFAULT or NULL. Columns with
default=... use the annotation's value; PHP property defaults have no effect. Any other
unassigned column is rejected before the statement reaches the database.
range of x is Name is a parse-time error when Name doesn't match a known
entity class.
Multi-Row Append
Comma-separated value tuples insert several rows in one statement. Every row must assign the same set of properties:
$entityManager->executeQuery('
range of u is App\Entities\UserEntity
append to u
(username = "carol", password = "pw1", banned = false),
(username = "dave", password = "pw2", banned = false)
');
getGeneratedId() returns null for a multi-row append — which row's identity value
it would even refer to is ambiguous, so it's left unset rather than guessed at.
Insert-from-Select
A bare column list (no =) followed by a retrieve copies rows from another range
instead of literal values. The presence or absence of = in the parenthesized list is the only
thing that distinguishes this form from the literal-values form above:
$entityManager->executeQuery('
range of dst is App\Entities\ArchivedOrderEntity
range of src is App\Entities\OrderEntity
append to dst (name, total) retrieve (src.name, src.total) where src.closed = true
');
Working with the Result
append returns a QuelResult with no fetchable rows — getAffectedRows()
and getGeneratedId() are the accessors that matter here, in place of iterating the result the
way a retrieve result is iterated:
$result = $entityManager->executeQuery($query, $parameters);
$affected = $result->getAffectedRows();
$newId = $result->getGeneratedId(); // null unless a single row was inserted with a generated PK
getGeneratedId() is populated only for single-row literal append. It is
null for multi-row append and insert-from-select. Upsert
statements follow a related but slightly different rule — see "Working with the Result" on that page.
RETURNING/output-clause support — the generated primary key comes back via
getGeneratedId(), not a SQL-level RETURNING/OUTPUT clause. MySQL has
no native equivalent to RETURNING at all.