Skip to content

Commit

Permalink
Merge branch '3.0.x' into 2.16.x-update-order-of-mapping-attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
soltmar authored Oct 11, 2023
2 parents 7e51a09 + 06eb00d commit f47d68c
Show file tree
Hide file tree
Showing 53 changed files with 326 additions and 1,102 deletions.
64 changes: 64 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,38 @@
To keep PHP mapping attributes consistent, order of arguments passed to above attributes has been changed
so `$targetEntity` is a first argument now. This change affects only non-named arguments usage.

## BC BREAK: AUTO keyword for identity generation defaults to IDENTITY for PostgreSQL now

When using the AUTO strategy to let Doctrine determine the identity generation mecehanism for
an entity, PostgreSQL now uses IDENTITY instead of SEQUENCE. When upgrading from ORM 2.x
and preference is on keeping the SEQUENCE based identity generation, then configure the ORM
this way:

```php
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\Mapping\ClassMetadata;

assert($configuration instanceof Configuration);
$configuration->setIdentityGenerationPreferences([
PostgreSQLPlatform::CLASS => ClassMetadata::GENERATOR_TYPE_SEQUENCE,
]);
```

## BC BREAK: Throw exceptions when using illegal attributes on Embeddable

There are only a few attributes allowed on an embeddable such as `#[Column]` or
`#[Embedded]`. Previously all others that target entity classes where ignored,
now they throw an exception.

## BC BREAK: Partial objects are removed

- The `PARTIAL` keyword in DQL no longer exists.
- `Doctrine\ORM\Query\AST\PartialObjectExpression`is removed.
- `Doctrine\ORM\Query\SqlWalker::HINT_PARTIAL` and
`Doctrine\ORM\Query::HINT_FORCE_PARTIAL_LOAD` are removed.
- `Doctrine\ORM\EntityManager*::getPartialReference()` is removed.

## BC BREAK: `Doctrine\ORM\Persister\Entity\EntityPersister::executeInserts()` return type changed to `void`

Implementors should adapt to the new signature, and should call
Expand Down Expand Up @@ -634,6 +666,38 @@ Use `toIterable()` instead.

# Upgrade to 2.17

## Deprecated: reliance on the non-optimal defaults that come with the `AUTO` identifier generation strategy

When the `AUTO` identifier generation strategy was introduced, the best
strategy at the time was selected for each database platform.
A lot of time has passed since then, and support for better strategies has been
added.

Because of that, it is now deprecated to rely on the historical defaults when
they differ from what we recommend now.

Instead, you should pick a strategy for each database platform you use, and it
will be used when using `AUTO`. As of now, only PostgreSQL is affected by this.
It is recommended that PostgreSQL user configure their new applications to use
`IDENTITY`:

```php
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\ORM\Configuration;

assert($configuration instanceof Configuration);
$configuration->setIdentityGenerationPreferences([
PostgreSQLPlatform::CLASS => ClassMetadata::GENERATOR_TYPE_IDENTITY,
]);
```

If migrating an existing application is too costly, the deprecation can be
addressed by configuring `SEQUENCE` as the default strategy.

## Deprecate `EntityManagerInterface::getPartialReference()`

This method does not have a replacement and will be removed in 3.0.

## Deprecate not-enabling lazy-ghosts

Not enabling lazy ghost objects is deprecated. In ORM 3.0, they will be always enabled.
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@
"doctrine/event-manager": "^1.2 || ^2",
"doctrine/inflector": "^1.4 || ^2.0",
"doctrine/instantiator": "^1.3 || ^2",
"doctrine/lexer": "^2.1 || ^3",
"doctrine/lexer": "^3",
"doctrine/persistence": "^3.1.1",
"psr/cache": "^1 || ^2 || ^3",
"symfony/console": "^5.4 || ^6.0 || ^7.0",
"symfony/var-exporter": "~6.2.13 || ^6.3.2"
"symfony/var-exporter": "~6.2.13 || ^6.3.2 || ^7.0"
},
"require-dev": {
"doctrine/coding-standard": "^12.0",
Expand Down
1 change: 0 additions & 1 deletion docs/en/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ Advanced Topics
* :doc:`TypedFieldMapper <reference/typedfieldmapper>`
* :doc:`Improving Performance <reference/improving-performance>`
* :doc:`Caching <reference/caching>`
* :doc:`Partial Objects <reference/partial-objects>`
* :doc:`Change Tracking Policies <reference/change-tracking-policies>`
* :doc:`Best Practices <reference/best-practices>`
* :doc:`Metadata Drivers <reference/metadata-drivers>`
Expand Down
37 changes: 27 additions & 10 deletions docs/en/reference/basic-mapping.rst
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,25 @@ the field that serves as the identifier with the ``#[Id]`` attribute.
</doctrine-mapping>
In most cases using the automatic generator strategy (``#[GeneratedValue]``) is
what you want. It defaults to the identifier generation mechanism your current
database vendor prefers: AUTO_INCREMENT with MySQL, sequences with PostgreSQL
and Oracle and so on.
what you want, but for backwards-compatibility reasons it might not. It
defaults to the identifier generation mechanism your current database
vendor preferred at the time that strategy was introduced:
``AUTO_INCREMENT`` with MySQL, sequences with PostgreSQL and Oracle and
so on.
We now recommend using ``IDENTITY`` for PostgreSQL, and you can achieve
that while still using the ``AUTO`` strategy, by configuring what it
defaults to.

.. code-block:: php
<?php
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\ORM\Configuration;
$config = new Configuration();
$config->setIdentityGenerationPreferences([
PostgreSQLPlatform::class => ClassMetadata::GENERATOR_TYPE_IDENTITY,
]);
.. _identifier-generation-strategies:

Expand All @@ -343,17 +359,18 @@ Here is the list of possible generation strategies:

- ``AUTO`` (default): Tells Doctrine to pick the strategy that is
preferred by the used database platform. The preferred strategies
are IDENTITY for MySQL, SQLite, MsSQL and SQL Anywhere and SEQUENCE
for Oracle and PostgreSQL. This strategy provides full portability.
- ``SEQUENCE``: Tells Doctrine to use a database sequence for ID
generation. This strategy does currently not provide full
portability. Sequences are supported by Oracle, PostgreSql and
SQL Anywhere.
are ``IDENTITY`` for MySQL, SQLite, MsSQL and SQL Anywhere and, for
historical reasons, ``SEQUENCE`` for Oracle and PostgreSQL. This
strategy provides full portability.
- ``IDENTITY``: Tells Doctrine to use special identity columns in
the database that generate a value on insertion of a row. This
strategy does currently not provide full portability and is
supported by the following platforms: MySQL/SQLite/SQL Anywhere
(AUTO\_INCREMENT), MSSQL (IDENTITY) and PostgreSQL (SERIAL).
(``AUTO_INCREMENT``), MSSQL (``IDENTITY``) and PostgreSQL (``SERIAL``).
- ``SEQUENCE``: Tells Doctrine to use a database sequence for ID
generation. This strategy does currently not provide full
portability. Sequences are supported by Oracle, PostgreSql and
SQL Anywhere.
- ``NONE``: Tells Doctrine that the identifiers are assigned (and
thus generated) by your code. The assignment must take place before
a new entity is passed to ``EntityManager#persist``. NONE is the
Expand Down
40 changes: 1 addition & 39 deletions docs/en/reference/dql-doctrine-query-language.rst
Original file line number Diff line number Diff line change
Expand Up @@ -518,33 +518,6 @@ when the DQL is switched to an arbitrary join.
- HAVING is applied to the results of a query after
aggregation (GROUP BY)


Partial Object Syntax
^^^^^^^^^^^^^^^^^^^^^

By default when you run a DQL query in Doctrine and select only a
subset of the fields for a given entity, you do not receive objects
back. Instead, you receive only arrays as a flat rectangular result
set, similar to how you would if you were just using SQL directly
and joining some data.

If you want to select partial objects you can use the ``partial``
DQL keyword:

.. code-block:: php
<?php
$query = $em->createQuery('SELECT partial u.{id, username} FROM CmsUser u');
$users = $query->getResult(); // array of partially loaded CmsUser objects
You use the partial syntax when joining as well:

.. code-block:: php
<?php
$query = $em->createQuery('SELECT partial u.{id, username}, partial a.{id, name} FROM CmsUser u JOIN u.articles a');
$users = $query->getResult(); // array of partially loaded CmsUser objects
"NEW" Operator Syntax
^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -1417,15 +1390,6 @@ exist mostly internal query hints that are not be consumed in
userland. However the following few hints are to be used in
userland:


- ``Query::HINT_FORCE_PARTIAL_LOAD`` - Allows to hydrate objects
although not all their columns are fetched. This query hint can be
used to handle memory consumption problems with large result-sets
that contain char or binary data. Doctrine has no way of implicitly
reloading this data. Partially loaded objects have to be passed to
``EntityManager::refresh()`` if they are to be reloaded fully from
the database. This query hint is deprecated and will be removed
in the future (\ `Details <https://github.com/doctrine/orm/issues/8471>`_)
- ``Query::HINT_REFRESH`` - This query is used internally by
``EntityManager::refresh()`` and can be used in userland as well.
If you specify this hint and a query returns the data for an entity
Expand Down Expand Up @@ -1678,10 +1642,8 @@ Select Expressions

.. code-block:: php
SelectExpression ::= (IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | PartialObjectExpression | "(" Subselect ")" | CaseExpression | NewObjectExpression) [["AS"] ["HIDDEN"] AliasResultVariable]
SelectExpression ::= (IdentificationVariable | ScalarExpression | AggregateExpression | FunctionDeclaration | "(" Subselect ")" | CaseExpression | NewObjectExpression) [["AS"] ["HIDDEN"] AliasResultVariable]
SimpleSelectExpression ::= (StateFieldPathExpression | IdentificationVariable | FunctionDeclaration | AggregateExpression | "(" Subselect ")" | ScalarExpression) [["AS"] AliasResultVariable]
PartialObjectExpression ::= "PARTIAL" IdentificationVariable "." PartialFieldSet
PartialFieldSet ::= "{" SimpleStateField {"," SimpleStateField}* "}"
NewObjectExpression ::= "NEW" AbstractSchemaName "(" NewObjectArg {"," NewObjectArg}* ")"
NewObjectArg ::= ScalarExpression | "(" Subselect ")"
Expand Down
98 changes: 0 additions & 98 deletions docs/en/reference/partial-objects.rst

This file was deleted.

1 change: 0 additions & 1 deletion docs/en/sidebar.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
reference/query-builder
reference/native-sql
reference/change-tracking-policies
reference/partial-objects
reference/attributes-reference
reference/xml-mapping
reference/php-mapping
Expand Down
14 changes: 8 additions & 6 deletions lib/Doctrine/ORM/AbstractQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Util\ClassUtils;
use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\Cache\QueryCacheProfile;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Result;
Expand Down Expand Up @@ -320,15 +321,16 @@ public function setParameters(ArrayCollection|array $parameters): static
/**
* Sets a query parameter.
*
* @param string|int $key The parameter position or name.
* @param mixed $value The parameter value.
* @param ParameterType|string|int|null $type The parameter type. If specified, the given value will be run through
* the type conversion of this type. This is usually not needed for
* strings and numeric types.
* @param string|int $key The parameter position or name.
* @param mixed $value The parameter value.
* @param ParameterType|ArrayParameterType|string|int|null $type The parameter type. If specified, the given value
* will be run through the type conversion of this
* type. This is usually not needed for strings and
* numeric types.
*
* @return $this
*/
public function setParameter(string|int $key, mixed $value, ParameterType|string|int|null $type = null): static
public function setParameter(string|int $key, mixed $value, ParameterType|ArrayParameterType|string|int|null $type = null): static
{
$existingParameter = $this->getParameter($key);

Expand Down
5 changes: 0 additions & 5 deletions lib/Doctrine/ORM/Cache/DefaultQueryCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
use Doctrine\ORM\PersistentCollection;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\UnitOfWork;

use function array_map;
Expand Down Expand Up @@ -211,10 +210,6 @@ public function put(QueryCacheKey $key, ResultSetMapping $rsm, mixed $result, ar
throw FeatureNotImplemented::nonSelectStatements();
}

if (($hints[SqlWalker::HINT_PARTIAL] ?? false) === true || ($hints[Query::HINT_FORCE_PARTIAL_LOAD] ?? false) === true) {
throw FeatureNotImplemented::partialEntities();
}

if (! ($key->cacheMode & Cache::MODE_PUT)) {
return false;
}
Expand Down
5 changes: 0 additions & 5 deletions lib/Doctrine/ORM/Cache/Exception/FeatureNotImplemented.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,4 @@ public static function nonSelectStatements(): self
{
return new self('Second-level cache query supports only select statements.');
}

public static function partialEntities(): self
{
return new self('Second level cache does not support partial entities.');
}
}
Loading

0 comments on commit f47d68c

Please sign in to comment.