Compare commits

...

8 Commits

Author SHA1 Message Date
HypeMC a381af4424 Document composite foreign keys (#12433) 2026-04-22 00:09:28 +02:00
HypeMC 81f6bb4d31 Fix errors in EBNF (#12430) 2026-04-21 23:52:48 +02:00
Grégoire Paris 65f5f49809 Merge pull request #12431 from HypeMC/fix-tests-dir-structure
Move leftover tests to new directory structure
2026-04-11 10:48:21 +02:00
HypeMC 11d7a91e62 Move leftover tests to new directory structure 2026-04-11 03:40:30 +02:00
Grégoire Paris f414d89b05 Merge pull request #12429 from derrabus/bugfix/getting-started-link
Fix "Install Composer" link on getting started documentation
2026-04-09 12:07:38 +02:00
Alexander M. Turek aa2eb71555 Fix "Install Composer" link on getting started documentation 2026-04-09 10:24:06 +02:00
Alexander M. Turek eecb1d8efd Merge pull request #12426 from doctrine/dependabot/github_actions/2.20.x/doctrine-b32f1f77d9 2026-04-05 08:54:38 +02:00
dependabot[bot] b9dd4fc963 Bump the doctrine group with 4 updates
Bumps the doctrine group with 4 updates: [doctrine/.github/.github/workflows/coding-standards.yml](https://github.com/doctrine/.github), [doctrine/.github/.github/workflows/composer-lint.yml](https://github.com/doctrine/.github), [doctrine/.github/.github/workflows/documentation.yml](https://github.com/doctrine/.github) and [doctrine/.github/.github/workflows/release-on-milestone-closed.yml](https://github.com/doctrine/.github).


Updates `doctrine/.github/.github/workflows/coding-standards.yml` from 14.0.0 to 15.0.0
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/14.0.0...15.0.0)

Updates `doctrine/.github/.github/workflows/composer-lint.yml` from 14.0.0 to 15.0.0
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/14.0.0...15.0.0)

Updates `doctrine/.github/.github/workflows/documentation.yml` from 14.0.0 to 15.0.0
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/14.0.0...15.0.0)

Updates `doctrine/.github/.github/workflows/release-on-milestone-closed.yml` from 14.0.0 to 15.0.0
- [Release notes](https://github.com/doctrine/.github/releases)
- [Commits](https://github.com/doctrine/.github/compare/14.0.0...15.0.0)

---
updated-dependencies:
- dependency-name: doctrine/.github/.github/workflows/coding-standards.yml
  dependency-version: 15.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: doctrine
- dependency-name: doctrine/.github/.github/workflows/composer-lint.yml
  dependency-version: 15.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: doctrine
- dependency-name: doctrine/.github/.github/workflows/documentation.yml
  dependency-version: 15.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: doctrine
- dependency-name: doctrine/.github/.github/workflows/release-on-milestone-closed.yml
  dependency-version: 15.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: doctrine
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-05 06:12:23 +00:00
11 changed files with 138 additions and 24 deletions
+1 -1
View File
@@ -24,4 +24,4 @@ on:
jobs:
coding-standards:
uses: "doctrine/.github/.github/workflows/coding-standards.yml@14.0.0"
uses: "doctrine/.github/.github/workflows/coding-standards.yml@15.0.0"
+1 -1
View File
@@ -17,4 +17,4 @@ on:
jobs:
composer-lint:
name: "Composer Lint"
uses: "doctrine/.github/.github/workflows/composer-lint.yml@14.0.0"
uses: "doctrine/.github/.github/workflows/composer-lint.yml@15.0.0"
+1 -1
View File
@@ -17,4 +17,4 @@ on:
jobs:
documentation:
name: "Documentation"
uses: "doctrine/.github/.github/workflows/documentation.yml@14.0.0"
uses: "doctrine/.github/.github/workflows/documentation.yml@15.0.0"
@@ -7,7 +7,7 @@ on:
jobs:
release:
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@14.0.0"
uses: "doctrine/.github/.github/workflows/release-on-milestone-closed.yml@15.0.0"
secrets:
GIT_AUTHOR_EMAIL: ${{ secrets.GIT_AUTHOR_EMAIL }}
GIT_AUTHOR_NAME: ${{ secrets.GIT_AUTHOR_NAME }}
@@ -30,6 +30,13 @@ a property referring to the other side.
To gain a full understanding of associations you should also read about :doc:`owning and
inverse sides of associations <unitofwork-associations>`
Composite Foreign Keys
----------------------
When the target entity has a composite primary key, you need to use multiple
join column mappings, one for each column of the composite key. See the
:doc:`Composite and Foreign Keys <../tutorials/composite-primary-keys>` tutorial for details.
Many-To-One, Unidirectional
---------------------------
@@ -1514,16 +1514,16 @@ Identifiers
IdentificationVariable ::= identifier
/* Alias Identification declaration (the "u" of "FROM User u") */
AliasIdentificationVariable :: = identifier
AliasIdentificationVariable ::= identifier
/* identifier that must be a class name (the "User" of "FROM User u"), possibly as a fully qualified class name or namespace-aliased */
AbstractSchemaName ::= fully_qualified_name | aliased_name | identifier
/* Alias ResultVariable declaration (the "total" of "COUNT(*) AS total") */
AliasResultVariable = identifier
AliasResultVariable ::= identifier
/* ResultVariable identifier usage of mapped field aliases (the "total" of "COUNT(*) AS total") */
ResultVariable = identifier
ResultVariable ::= identifier
/* identifier that must be a field (the "name" of "u.name") */
/* This is responsible to know if the field exists in Object, no matter if it's a relation or a simple field */
@@ -1678,7 +1678,7 @@ Scalar and Type Expressions
.. code-block:: php
ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary | StateFieldPathExpression | BooleanPrimary | CaseExpression | InstanceOfExpression
ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary | StateFieldPathExpression | BooleanPrimary | CaseExpression | InstanceOfExpression
StringExpression ::= StringPrimary | ResultVariable | "(" Subselect ")"
StringPrimary ::= StateFieldPathExpression | string | InputParameter | FunctionsReturningStrings | AggregateExpression | CaseExpression
BooleanExpression ::= BooleanPrimary | "(" Subselect ")"
@@ -1704,14 +1704,14 @@ Case Expressions
.. code-block:: php
CaseExpression ::= GeneralCaseExpression | SimpleCaseExpression | CoalesceExpression | NullifExpression
CaseExpression ::= GeneralCaseExpression | SimpleCaseExpression | CoalesceExpression | NullIfExpression
GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END"
WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression
SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END"
CaseOperand ::= StateFieldPathExpression | TypeDiscriminator
CaseOperand ::= StateFieldPathExpression
SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression
CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")"
NullifExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"
NullIfExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"
Other Expressions
~~~~~~~~~~~~~~~~~
@@ -1736,7 +1736,7 @@ Functions
.. code-block:: php
FunctionDeclaration ::= FunctionsReturningStrings | FunctionsReturningNumerics | FunctionsReturningDateTime
FunctionDeclaration ::= FunctionsReturningStrings | FunctionsReturningNumerics | FunctionsReturningDatetime
FunctionsReturningNumerics ::=
"LENGTH" "(" StringPrimary ")" |
@@ -1749,7 +1749,7 @@ Functions
"BIT_AND" "(" ArithmeticPrimary "," ArithmeticPrimary ")" |
"BIT_OR" "(" ArithmeticPrimary "," ArithmeticPrimary ")"
FunctionsReturningDateTime ::=
FunctionsReturningDatetime ::=
"CURRENT_DATE" |
"CURRENT_TIME" |
"CURRENT_TIMESTAMP" |
+111 -3
View File
@@ -135,14 +135,122 @@ And for querying you can use arrays to both DQL and EntityRepositories:
->setParameter(2, 2010)
->getSingleResult();
You can also use this entity in associations. Doctrine will then generate two foreign keys one for ``name``
and to ``year`` to the related entities.
.. note::
This example shows how you can nicely solve the requirement for existing
values before ``EntityManager#persist()``: By adding them as mandatory values for the constructor.
You can also use this entity in associations. Doctrine will then generate a composite foreign key
using the ``name`` and ``year`` columns on the related entities.
To define such an association, you need to use multiple join column mappings, one for each
column of the composite primary key:
.. configuration-block::
.. code-block:: attribute
<?php
namespace VehicleCatalogue\Model;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\JoinColumn;
use Doctrine\ORM\Mapping\ManyToOne;
#[Entity]
class Registration
{
#[Id, Column, GeneratedValue]
private int|null $id = null;
#[ManyToOne(targetEntity: Car::class)]
#[JoinColumn(name: 'car_name', referencedColumnName: 'name')]
#[JoinColumn(name: 'car_year', referencedColumnName: 'year')]
private Car|null $car = null;
}
.. code-block:: annotation
<?php
namespace VehicleCatalogue\Model;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Registration
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue
*/
private int|null $id = null;
/**
* @ORM\ManyToOne(targetEntity="Car")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="car_name", referencedColumnName="name"),
* @ORM\JoinColumn(name="car_year", referencedColumnName="year")
* })
*/
private Car|null $car = null;
}
.. code-block:: xml
<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
https://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
<entity name="VehicleCatalogue\Model\Registration">
<id name="id" type="integer">
<generator strategy="AUTO" />
</id>
<many-to-one field="car" target-entity="Car">
<join-column name="car_name" referenced-column-name="name" />
<join-column name="car_year" referenced-column-name="year" />
</many-to-one>
</entity>
</doctrine-mapping>
.. code-block:: yaml
VehicleCatalogue\Model\Registration:
type: entity
id:
id:
type: integer
generator:
strategy: AUTO
manyToOne:
car:
targetEntity: Car
joinColumns:
car_name:
referencedColumnName: name
car_year:
referencedColumnName: year
This generates the following SQL:
.. code-block:: sql
CREATE TABLE Registration (
id INT AUTO_INCREMENT NOT NULL,
car_name VARCHAR(255) DEFAULT NULL,
car_year INT DEFAULT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB;
ALTER TABLE Registration ADD FOREIGN KEY (car_name, car_year) REFERENCES Car(name, year);
Identity through foreign Entities
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+1 -2
View File
@@ -18,8 +18,7 @@ before. There are some prerequisites for the tutorial that have to be
installed:
- PHP (latest stable version)
- Composer Package Manager (\ `Install Composer
<https://getcomposer.org/doc/00-intro.md>`_)
- Composer Package Manager (\ `Install Composer <https://getcomposer.org/doc/00-intro.md>`_)
The code of this tutorial is `available on Github <https://github.com/doctrine/doctrine2-orm-tutorial>`_.
+6 -6
View File
@@ -1994,7 +1994,7 @@ class Parser
}
/**
* ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DateTimePrimary |
* ScalarExpression ::= SimpleArithmeticExpression | StringPrimary | DatetimePrimary |
* StateFieldPathExpression | BooleanPrimary | CaseExpression |
* InstanceOfExpression
*
@@ -2077,14 +2077,14 @@ class Parser
}
/**
* CaseExpression ::= GeneralCaseExpression | SimpleCaseExpression | CoalesceExpression | NullifExpression
* CaseExpression ::= GeneralCaseExpression | SimpleCaseExpression | CoalesceExpression | NullIfExpression
* GeneralCaseExpression ::= "CASE" WhenClause {WhenClause}* "ELSE" ScalarExpression "END"
* WhenClause ::= "WHEN" ConditionalExpression "THEN" ScalarExpression
* SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END"
* CaseOperand ::= StateFieldPathExpression | TypeDiscriminator
* CaseOperand ::= StateFieldPathExpression
* SimpleWhenClause ::= "WHEN" ScalarExpression "THEN" ScalarExpression
* CoalesceExpression ::= "COALESCE" "(" ScalarExpression {"," ScalarExpression}* ")"
* NullifExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"
* NullIfExpression ::= "NULLIF" "(" ScalarExpression "," ScalarExpression ")"
*
* @return mixed One of the possible expressions or subexpressions.
*/
@@ -2188,7 +2188,7 @@ class Parser
/**
* SimpleCaseExpression ::= "CASE" CaseOperand SimpleWhenClause {SimpleWhenClause}* "ELSE" ScalarExpression "END"
* CaseOperand ::= StateFieldPathExpression | TypeDiscriminator
* CaseOperand ::= StateFieldPathExpression
*
* @return AST\SimpleCaseExpression
*/
@@ -3603,7 +3603,7 @@ class Parser
}
/**
* FunctionsReturningDateTime ::=
* FunctionsReturningDatetime ::=
* "CURRENT_DATE" |
* "CURRENT_TIME" |
* "CURRENT_TIMESTAMP" |