mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75b4b88c5b | ||
|
|
d9e59d6862 | ||
|
|
5fa94969de | ||
|
|
f2c3ddac97 | ||
|
|
46f0da9ffa | ||
|
|
1e832a6782 | ||
|
|
56bdb44efd | ||
|
|
fffac44991 | ||
|
|
e42b3d6584 | ||
|
|
7ab2c3abbd | ||
|
|
498c816b65 | ||
|
|
eec740079d | ||
|
|
c359715a97 | ||
|
|
f3e55fae9f | ||
|
|
91c3bd4121 | ||
|
|
e6cf12c66f |
@@ -12,21 +12,27 @@
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "2.9",
|
||||
"branchName": "2.9.x",
|
||||
"slug": "2.9",
|
||||
"name": "2.10",
|
||||
"branchName": "2.10.x",
|
||||
"slug": "2.10",
|
||||
"upcoming": true
|
||||
},
|
||||
{
|
||||
"name": "2.8",
|
||||
"branchName": "2.8.x",
|
||||
"slug": "2.8",
|
||||
"name": "2.9",
|
||||
"branchName": "2.9.x",
|
||||
"slug": "2.9",
|
||||
"current": true,
|
||||
"aliases": [
|
||||
"current",
|
||||
"stable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "2.8",
|
||||
"branchName": "2.8.x",
|
||||
"slug": "2.8",
|
||||
"maintained": false
|
||||
},
|
||||
{
|
||||
"name": "2.7",
|
||||
"branchName": "2.7",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"ext-pdo": "*",
|
||||
"composer/package-versions-deprecated": "^1.8",
|
||||
"doctrine/annotations": "^1.13",
|
||||
"doctrine/cache": "^1.11|^2.0",
|
||||
"doctrine/cache": "^1.11.3|^2.0.3",
|
||||
"doctrine/collections": "^1.5",
|
||||
"doctrine/common": "^3.0.3",
|
||||
"doctrine/dbal": "^2.13.0",
|
||||
|
||||
@@ -10,7 +10,7 @@ code should look like. We will implement it on a
|
||||
`Layer Supertype <http://martinfowler.com/eaaCatalog/layerSupertype.html>`_
|
||||
for all our domain objects.
|
||||
|
||||
.. warning::
|
||||
.. note::
|
||||
|
||||
The notify change tracking policy is deprecated and will be removed in ORM 3.0.
|
||||
(`Details <https://github.com/doctrine/orm/issues/8383>`_)
|
||||
|
||||
@@ -113,7 +113,7 @@ Optional attributes:
|
||||
- **unique**: Boolean value to determine if the value of the column
|
||||
should be unique across all rows of the underlying entities table.
|
||||
|
||||
- **nullable**: Determines if NULL values allowed for this column. If not specified, default value is false. When using typed properties on entity class defaults to true when property is nullable.
|
||||
- **nullable**: Determines if NULL values allowed for this column. If not specified, default value is false.
|
||||
|
||||
- **options**: Array of additional options:
|
||||
|
||||
@@ -350,7 +350,7 @@ in order to specify that it is an embedded class.
|
||||
|
||||
Required attributes:
|
||||
|
||||
- **class**: The embeddable class
|
||||
- **class**: The embeddable class. You can omit this value if you use a PHP property type instead.
|
||||
|
||||
|
||||
.. code-block:: php
|
||||
@@ -649,8 +649,6 @@ Optional attributes:
|
||||
constraint level. Defaults to false.
|
||||
- **nullable**: Determine whether the related entity is required, or if
|
||||
null is an allowed state for the relation. Defaults to true.
|
||||
When using typed properties on entity class defaults to false when
|
||||
property is not nullable.
|
||||
- **onDelete**: Cascade Action (Database-level)
|
||||
- **columnDefinition**: DDL SQL snippet that starts after the column
|
||||
name and specifies the complete (non-portable!) column definition.
|
||||
|
||||
@@ -10,46 +10,46 @@ annotation metadata supported since the first version 2.0.
|
||||
Index
|
||||
-----
|
||||
|
||||
- :ref:`#[Column] <annref_column>`
|
||||
- :ref:`#[Cache] <annref_cache>`
|
||||
- :ref:`#[ChangeTrackingPolicy <annref_changetrackingpolicy>`
|
||||
- :ref:`#[CustomIdGenerator] <annref_customidgenerator>`
|
||||
- :ref:`#[DiscriminatorColumn] <annref_discriminatorcolumn>`
|
||||
- :ref:`#[DiscriminatorMap] <annref_discriminatormap>`
|
||||
- :ref:`#[Embeddable] <annref_embeddable>`
|
||||
- :ref:`#[Embedded] <annref_embedded>`
|
||||
- :ref:`#[Entity] <annref_entity>`
|
||||
- :ref:`#[GeneratedValue] <annref_generatedvalue>`
|
||||
- :ref:`#[HasLifecycleCallbacks] <annref_haslifecyclecallbacks>`
|
||||
- :ref:`#[Index] <annref_index>`
|
||||
- :ref:`#[Id] <annref_id>`
|
||||
- :ref:`#[InheritanceType] <annref_inheritancetype>`
|
||||
- :ref:`#[JoinColumn] <annref_joincolumn>`
|
||||
- :ref:`#[JoinColumns] <annref_joincolumns>`
|
||||
- :ref:`#[JoinTable] <annref_jointable>`
|
||||
- :ref:`#[ManyToOne] <annref_manytoone>`
|
||||
- :ref:`#[ManyToMany] <annref_manytomany>`
|
||||
- :ref:`#[MappedSuperclass] <annref_mappedsuperclass>`
|
||||
- :ref:`#[OneToOne] <annref_onetoone>`
|
||||
- :ref:`#[OneToMany] <annref_onetomany>`
|
||||
- :ref:`#[OrderBy] <annref_orderby>`
|
||||
- :ref:`#[PostLoad] <annref_postload>`
|
||||
- :ref:`#[PostPersist] <annref_postpersist>`
|
||||
- :ref:`#[PostRemove] <annref_postremove>`
|
||||
- :ref:`#[PostUpdate] <annref_postupdate>`
|
||||
- :ref:`#[PrePersist] <annref_prepersist>`
|
||||
- :ref:`#[PreRemove] <annref_preremove>`
|
||||
- :ref:`#[PreUpdate] <annref_preupdate>`
|
||||
- :ref:`#[SequenceGenerator] <annref_sequencegenerator>`
|
||||
- :ref:`#[Table] <annref_table>`
|
||||
- :ref:`#[UniqueConstraint] <annref_uniqueconstraint>`
|
||||
- :ref:`#[Version] <annref_version>`
|
||||
- :ref:`#[Column] <attrref_column>`
|
||||
- :ref:`#[Cache] <attrref_cache>`
|
||||
- :ref:`#[ChangeTrackingPolicy <attrref_changetrackingpolicy>`
|
||||
- :ref:`#[CustomIdGenerator] <attrref_customidgenerator>`
|
||||
- :ref:`#[DiscriminatorColumn] <attrref_discriminatorcolumn>`
|
||||
- :ref:`#[DiscriminatorMap] <attrref_discriminatormap>`
|
||||
- :ref:`#[Embeddable] <attrref_embeddable>`
|
||||
- :ref:`#[Embedded] <attrref_embedded>`
|
||||
- :ref:`#[Entity] <attrref_entity>`
|
||||
- :ref:`#[GeneratedValue] <attrref_generatedvalue>`
|
||||
- :ref:`#[HasLifecycleCallbacks] <attrref_haslifecyclecallbacks>`
|
||||
- :ref:`#[Index] <attrref_index>`
|
||||
- :ref:`#[Id] <attrref_id>`
|
||||
- :ref:`#[InheritanceType] <attrref_inheritancetype>`
|
||||
- :ref:`#[JoinColumn] <attrref_joincolumn>`
|
||||
- :ref:`#[JoinColumns] <attrref_joincolumns>`
|
||||
- :ref:`#[JoinTable] <attrref_jointable>`
|
||||
- :ref:`#[ManyToOne] <attrref_manytoone>`
|
||||
- :ref:`#[ManyToMany] <attrref_manytomany>`
|
||||
- :ref:`#[MappedSuperclass] <attrref_mappedsuperclass>`
|
||||
- :ref:`#[OneToOne] <attrref_onetoone>`
|
||||
- :ref:`#[OneToMany] <attrref_onetomany>`
|
||||
- :ref:`#[OrderBy] <attrref_orderby>`
|
||||
- :ref:`#[PostLoad] <attrref_postload>`
|
||||
- :ref:`#[PostPersist] <attrref_postpersist>`
|
||||
- :ref:`#[PostRemove] <attrref_postremove>`
|
||||
- :ref:`#[PostUpdate] <attrref_postupdate>`
|
||||
- :ref:`#[PrePersist] <attrref_prepersist>`
|
||||
- :ref:`#[PreRemove] <attrref_preremove>`
|
||||
- :ref:`#[PreUpdate] <attrref_preupdate>`
|
||||
- :ref:`#[SequenceGenerator] <attrref_sequencegenerator>`
|
||||
- :ref:`#[Table] <attrref_table>`
|
||||
- :ref:`#[UniqueConstraint] <attrref_uniqueconstraint>`
|
||||
- :ref:`#[Version] <attrref_version>`
|
||||
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. _annref_column:
|
||||
.. _attrref_column:
|
||||
|
||||
#[Column]
|
||||
~~~~~~~~~
|
||||
@@ -122,7 +122,7 @@ Optional attributes:
|
||||
attribute still handles the conversion between PHP and Database
|
||||
values. If you use this attribute on a column that is used for
|
||||
joins between tables you should also take a look at
|
||||
:ref:`#[JoinColumn] <annref_joincolumn>`.
|
||||
:ref:`#[JoinColumn] <attrref_joincolumn>`.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -159,7 +159,7 @@ Examples:
|
||||
)]
|
||||
protected $loginCount;
|
||||
|
||||
.. _annref_cache:
|
||||
.. _attrref_cache:
|
||||
|
||||
#[Cache]
|
||||
~~~~~~~~
|
||||
@@ -170,7 +170,7 @@ Optional attributes:
|
||||
- **usage**: One of ``READ_ONLY``, ``READ_WRITE`` or ``NONSTRICT_READ_WRITE``, By default this is ``READ_ONLY``.
|
||||
- **region**: An specific region name
|
||||
|
||||
.. _annref_changetrackingpolicy:
|
||||
.. _attrref_changetrackingpolicy:
|
||||
|
||||
#[ChangeTrackingPolicy]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -203,12 +203,12 @@ Example:
|
||||
]
|
||||
class User {}
|
||||
|
||||
.. _annref_customidgenerator:
|
||||
.. _attrref_customidgenerator:
|
||||
|
||||
#[CustomIdGenerator]
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This attribute allows you to specify a user-provided class to generate identifiers. This attribute only works when both :ref:`#[Id] <annref_id>` and :ref:`#[GeneratedValue(strategy: "CUSTOM")] <annref_generatedvalue>` are specified.
|
||||
This attribute allows you to specify a user-provided class to generate identifiers. This attribute only works when both :ref:`#[Id] <attrref_id>` and :ref:`#[GeneratedValue(strategy: "CUSTOM")] <attrref_generatedvalue>` are specified.
|
||||
|
||||
Required attributes:
|
||||
|
||||
@@ -231,7 +231,7 @@ Example:
|
||||
#[CustomIdGenerator(class: MyIdGenerator::class)]
|
||||
public $id;
|
||||
|
||||
.. _annref_discriminatorcolumn:
|
||||
.. _attrref_discriminatorcolumn:
|
||||
|
||||
#[DiscriminatorColumn]
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -256,7 +256,7 @@ Optional attributes:
|
||||
- **type**: By default this is string.
|
||||
- **length**: By default this is 255.
|
||||
|
||||
.. _annref_discriminatormap:
|
||||
.. _attrref_discriminatormap:
|
||||
|
||||
#[DiscriminatorMap]
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
@@ -286,13 +286,13 @@ depending on whether the classes are in the namespace or not.
|
||||
}
|
||||
|
||||
|
||||
.. _annref_embeddable:
|
||||
.. _attrref_embeddable:
|
||||
|
||||
#[Embeddable]
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The embeddable attribute is required on a class, in order to make it
|
||||
embeddable inside an entity. It works together with the :ref:`#[Embedded] <annref_embedded>`
|
||||
embeddable inside an entity. It works together with the :ref:`#[Embedded] <attrref_embedded>`
|
||||
attribute to establish the relationship between the two classes.
|
||||
|
||||
.. code-block:: php
|
||||
@@ -311,7 +311,7 @@ attribute to establish the relationship between the two classes.
|
||||
private $address;
|
||||
|
||||
|
||||
.. _annref_embedded:
|
||||
.. _attrref_embedded:
|
||||
|
||||
#[Embedded]
|
||||
~~~~~~~~~~~
|
||||
@@ -323,7 +323,7 @@ Required attributes:
|
||||
|
||||
- **class**: The embeddable class
|
||||
|
||||
.. _annref_entity:
|
||||
.. _attrref_entity:
|
||||
|
||||
#[Entity]
|
||||
~~~~~~~~~
|
||||
@@ -355,13 +355,13 @@ Example:
|
||||
//...
|
||||
}
|
||||
|
||||
.. _annref_entity_result:
|
||||
.. _attrref_entity_result:
|
||||
|
||||
#[GeneratedValue]
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
Specifies which strategy is used for identifier generation for an
|
||||
instance variable which is annotated by :ref:`#[Id] <annref_id>`. This
|
||||
instance variable which is annotated by :ref:`#[Id] <attrref_id>`. This
|
||||
attribute is optional and only has meaning when used in
|
||||
conjunction with #[Id].
|
||||
|
||||
@@ -387,7 +387,7 @@ Example:
|
||||
#[Id, Column(type: "integer"), GeneratedValue(strategy="IDENTITY")]
|
||||
protected $id = null;
|
||||
|
||||
.. _annref_haslifecyclecallbacks:
|
||||
.. _attrref_haslifecyclecallbacks:
|
||||
|
||||
#[HasLifecycleCallbacks]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -415,7 +415,7 @@ Example:
|
||||
public function sendOptinMail() {}
|
||||
}
|
||||
|
||||
.. _annref_index:
|
||||
.. _attrref_index:
|
||||
|
||||
#[Index]
|
||||
~~~~~~~~
|
||||
@@ -466,7 +466,7 @@ Example with partial indexes:
|
||||
{
|
||||
}
|
||||
|
||||
.. _annref_id:
|
||||
.. _attrref_id:
|
||||
|
||||
#[Id]
|
||||
~~~~~
|
||||
@@ -488,7 +488,7 @@ Example:
|
||||
#[Id, Column(type="integer")]
|
||||
protected $id = null;
|
||||
|
||||
.. _annref_inheritancetype:
|
||||
.. _attrref_inheritancetype:
|
||||
|
||||
#[InheritanceType]
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
@@ -499,8 +499,8 @@ inheritance. Currently Single Table and Class Table Inheritance are
|
||||
supported.
|
||||
|
||||
This attribute has always been used in conjunction with the
|
||||
:ref:`#[DiscriminatorMap] <annref_discriminatormap>` and
|
||||
:ref:`#[DiscriminatorColumn] <annref_discriminatorcolumn>` attributes.
|
||||
:ref:`#[DiscriminatorMap] <attrref_discriminatormap>` and
|
||||
:ref:`#[DiscriminatorColumn] <attrref_discriminatorcolumn>` attributes.
|
||||
|
||||
Examples:
|
||||
|
||||
@@ -530,14 +530,14 @@ Examples:
|
||||
// ...
|
||||
}
|
||||
|
||||
.. _annref_joincolumn:
|
||||
.. _attrref_joincolumn:
|
||||
|
||||
#[JoinColumn], #[InverseJoinColumn]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This attribute is used in the context of relations in
|
||||
:ref:`#[ManyToOne] <annref_manytoone>`, :ref:`#[OneToOne] <annref_onetoone>` fields
|
||||
and in the Context of a :ref:`#[ManyToMany] <annref_manytomany>`. If this attribute or both *name* and *referencedColumnName*
|
||||
:ref:`#[ManyToOne] <attrref_manytoone>`, :ref:`#[OneToOne] <attrref_onetoone>` fields
|
||||
and in the Context of a :ref:`#[ManyToMany] <attrref_manytomany>`. If this attribute or both *name* and *referencedColumnName*
|
||||
are missing they will be computed considering the field's name and the current
|
||||
:doc:`naming strategy <namingstrategy>`.
|
||||
|
||||
@@ -564,7 +564,7 @@ Optional attributes:
|
||||
this attribute on ``#[JoinColumn]`` is necessary if you need slightly
|
||||
different column definitions for joining columns, for example
|
||||
regarding NULL/NOT NULL defaults. However by default a
|
||||
"columnDefinition" attribute on :ref:`#[Column] <annref_column>` also sets
|
||||
"columnDefinition" attribute on :ref:`#[Column] <attrref_column>` also sets
|
||||
the related ``#[JoinColumn]``'s columnDefinition. This is necessary to
|
||||
make foreign keys work.
|
||||
|
||||
@@ -580,13 +580,13 @@ Example:
|
||||
#[JoinColumn(name: "customer_id", referencedColumnName: "id")]
|
||||
private $customer;
|
||||
|
||||
.. _annref_jointable:
|
||||
.. _attrref_jointable:
|
||||
|
||||
#[JoinTable]
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Using
|
||||
:ref:`#[ManytoMany] <annref_manytomany>` on the owning side of the relation
|
||||
:ref:`#[ManytoMany] <attrref_manytomany>` on the owning side of the relation
|
||||
requires to specify the #[JoinTable] attribute which describes the
|
||||
details of the database join table. If you do not specify
|
||||
``#[JoinTable]`` on these relations reasonable mapping defaults apply
|
||||
@@ -612,7 +612,7 @@ Example:
|
||||
#[JoinTable(name: "users_phonenumbers")]
|
||||
public $phonenumbers;
|
||||
|
||||
.. _annref_manytoone:
|
||||
.. _attrref_manytoone:
|
||||
|
||||
#[ManyToOne]
|
||||
~~~~~~~~~~~~
|
||||
@@ -645,13 +645,13 @@ Example:
|
||||
#[ManyToOne(targetEntity: "Cart", cascade: ["all"], fetch: "EAGER")]
|
||||
private $cart;
|
||||
|
||||
.. _annref_manytomany:
|
||||
.. _attrref_manytomany:
|
||||
|
||||
#[ManyToMany]
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Defines that the annotated instance variable holds a many-to-many relationship
|
||||
between two entities. :ref:`#[JoinTable] <annref_jointable>` is an
|
||||
between two entities. :ref:`#[JoinTable] <attrref_jointable>` is an
|
||||
additional, optional attribute that has reasonable default
|
||||
configuration values using the table and names of the two related
|
||||
entities.
|
||||
@@ -703,7 +703,7 @@ Example:
|
||||
#[ManyToMany(targetEntity: "User", mappedBy: "groups")]
|
||||
private $features;
|
||||
|
||||
.. _annref_mappedsuperclass:
|
||||
.. _attrref_mappedsuperclass:
|
||||
|
||||
#[MappedSuperclass]
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
@@ -742,15 +742,15 @@ Example:
|
||||
// ... fields and methods
|
||||
}
|
||||
|
||||
.. _annref_onetoone:
|
||||
.. _attrref_onetoone:
|
||||
|
||||
#[OneToOne]
|
||||
~~~~~~~~~~~
|
||||
|
||||
The ``#[OneToOne]`` attribute works almost exactly as the
|
||||
:ref:`#[ManyToOne] <annref_manytoone>` with one additional option which can
|
||||
:ref:`#[ManyToOne] <attrref_manytoone>` with one additional option which can
|
||||
be specified. When no
|
||||
:ref:`#[JoinColumn] <annref_joincolumn>` is specified it defaults to using the target entity table and
|
||||
:ref:`#[JoinColumn] <attrref_joincolumn>` is specified it defaults to using the target entity table and
|
||||
primary key column names and the current naming strategy to determine a name for the join column.
|
||||
|
||||
Required attributes:
|
||||
@@ -778,7 +778,7 @@ Example:
|
||||
#[JoinColumn(name: "customer_id", referencedColumnName: "id")]
|
||||
private $customer;
|
||||
|
||||
.. _annref_onetomany:
|
||||
.. _attrref_onetomany:
|
||||
|
||||
#[OneToMany]
|
||||
~~~~~~~~~~~~
|
||||
@@ -816,13 +816,13 @@ Example:
|
||||
]
|
||||
public $phonenumbers;
|
||||
|
||||
.. _annref_orderby:
|
||||
.. _attrref_orderby:
|
||||
|
||||
#[OrderBy]
|
||||
~~~~~~~~~~
|
||||
|
||||
Optional attribute that can be specified with a
|
||||
:ref:`#[ManyToMany] <annref_manytomany>` or :ref:`#[OneToMany] <annref_onetomany>`
|
||||
:ref:`#[ManyToMany] <attrref_manytomany>` or :ref:`#[OneToMany] <attrref_onetomany>`
|
||||
attribute to specify by which criteria the collection should be
|
||||
retrieved from the database by using an ORDER BY clause.
|
||||
|
||||
@@ -841,7 +841,7 @@ positional statement. Multiple Fields are separated by a comma (,).
|
||||
The referenced field names have to exist on the ``targetEntity``
|
||||
class of the ``#[ManyToMany]`` or ``#[OneToMany]`` attribute.
|
||||
|
||||
.. _annref_postload:
|
||||
.. _attrref_postload:
|
||||
|
||||
#[PostLoad]
|
||||
~~~~~~~~~~~~~~
|
||||
@@ -850,7 +850,7 @@ Marks a method on the entity to be called as a ``#[PostLoad]`` event.
|
||||
Only works with ``#[HasLifecycleCallbacks]`` in the entity class PHP
|
||||
level.
|
||||
|
||||
.. _annref_postpersist:
|
||||
.. _attrref_postpersist:
|
||||
|
||||
#[PostPersist]
|
||||
~~~~~~~~~~~~~~
|
||||
@@ -859,7 +859,7 @@ Marks a method on the entity to be called as a ``#[PostPersist]`` event.
|
||||
Only works with ``#[HasLifecycleCallbacks]`` in the entity class PHP
|
||||
level.
|
||||
|
||||
.. _annref_postremove:
|
||||
.. _attrref_postremove:
|
||||
|
||||
#[PostRemove]
|
||||
~~~~~~~~~~~~~~
|
||||
@@ -868,7 +868,7 @@ Marks a method on the entity to be called as a ``#[PostRemove]`` event.
|
||||
Only works with ``#[HasLifecycleCallbacks]`` in the entity class PHP
|
||||
level.
|
||||
|
||||
.. _annref_postupdate:
|
||||
.. _attrref_postupdate:
|
||||
|
||||
#[PostUpdate]
|
||||
~~~~~~~~~~~~~~
|
||||
@@ -877,7 +877,7 @@ Marks a method on the entity to be called as a ``#[PostUpdate]`` event.
|
||||
Only works with ``#[HasLifecycleCallbacks]`` in the entity class PHP
|
||||
level.
|
||||
|
||||
.. _annref_prepersist:
|
||||
.. _attrref_prepersist:
|
||||
|
||||
#[PrePersist]
|
||||
~~~~~~~~~~~~~~
|
||||
@@ -886,7 +886,7 @@ Marks a method on the entity to be called as a ``#[PrePersist]`` event.
|
||||
Only works with ``#[HasLifecycleCallbacks]`` in the entity class PHP
|
||||
level.
|
||||
|
||||
.. _annref_preremove:
|
||||
.. _attrref_preremove:
|
||||
|
||||
#[PreRemove]
|
||||
~~~~~~~~~~~~~~
|
||||
@@ -895,7 +895,7 @@ Marks a method on the entity to be called as a #``[PreRemove]`` event.
|
||||
Only works with ``#[HasLifecycleCallbacks]`` in the entity class PHP
|
||||
level.
|
||||
|
||||
.. _annref_preupdate:
|
||||
.. _attrref_preupdate:
|
||||
|
||||
#[PreUpdate]
|
||||
~~~~~~~~~~~~~~
|
||||
@@ -904,7 +904,7 @@ Marks a method on the entity to be called as a ``#[PreUpdate]`` event.
|
||||
Only works with ``#[HasLifecycleCallbacks]`` in the entity class PHP
|
||||
level.
|
||||
|
||||
.. _annref_sequencegenerator:
|
||||
.. _attrref_sequencegenerator:
|
||||
|
||||
#[SequenceGenerator]
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -941,7 +941,7 @@ Example:
|
||||
#[SequenceGenerator(sequenceName: "tablename_seq", initialValue: 1, allocationSize: 100)]
|
||||
protected $id = null;
|
||||
|
||||
.. _annref_table:
|
||||
.. _attrref_table:
|
||||
|
||||
#[Table]
|
||||
~~~~~~~~
|
||||
@@ -971,7 +971,7 @@ Example:
|
||||
#[Table(name: "user", schema: "schema_name")]
|
||||
class User { }
|
||||
|
||||
.. _annref_uniqueconstraint:
|
||||
.. _attrref_uniqueconstraint:
|
||||
|
||||
#[UniqueConstraint]
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
@@ -1008,16 +1008,16 @@ Basic example:
|
||||
{
|
||||
}
|
||||
|
||||
.. _annref_version:
|
||||
.. _attrref_version:
|
||||
|
||||
#[Version]
|
||||
~~~~~~~~~~
|
||||
|
||||
Marker attribute that defines a specified column as version attribute used in
|
||||
an :ref:`optimistic locking <transactions-and-concurrency_optimistic-locking>`
|
||||
scenario. It only works on :ref:`#[Column] <annref_column>` attributes that have
|
||||
scenario. It only works on :ref:`#[Column] <attrref_column>` attributes that have
|
||||
the type ``integer`` or ``datetime``. Setting ``#[Version]`` on a property with
|
||||
:ref:`#[Id <annref_id>` is not supported.
|
||||
:ref:`#[Id <attrref_id>` is not supported.
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ This policy can be configured as follows:
|
||||
Notify
|
||||
~~~~~~
|
||||
|
||||
.. warning::
|
||||
.. note::
|
||||
|
||||
The notify change tracking policy is deprecated and will be removed in ORM 3.0.
|
||||
(`Details <https://github.com/doctrine/orm/issues/8383>`_)
|
||||
|
||||
@@ -274,6 +274,9 @@ be a leaf entity in the inheritance hierarchy, (ie. have no subclasses).
|
||||
Otherwise Doctrine *CANNOT* create proxy instances
|
||||
of this entity and will *ALWAYS* load the entity eagerly.
|
||||
|
||||
There is also another important performance consideration that it is *NOT POSSIBLE*
|
||||
to query for the base entity without any LEFT JOINs to the sub-types.
|
||||
|
||||
SQL Schema considerations
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ Partial Objects
|
||||
===============
|
||||
|
||||
|
||||
.. warning::
|
||||
.. note::
|
||||
|
||||
Creating Partial Objects through DQL is deprecated and
|
||||
will be removed in the future, use data transfer object
|
||||
|
||||
@@ -134,6 +134,10 @@ optimize the performance of the Flush Operation:
|
||||
explicit strategies of notifying the UnitOfWork what objects/properties
|
||||
changed.
|
||||
|
||||
.. note::
|
||||
|
||||
Flush only a single entity with ``$entityManager->flush($entity)`` is deprecated and will be removed in ORM 3.0.
|
||||
(`Details <https://github.com/doctrine/orm/issues/8459>`_)
|
||||
|
||||
Query Internals
|
||||
---------------
|
||||
|
||||
@@ -309,7 +309,7 @@
|
||||
|
||||
<xs:complexType name="embedded">
|
||||
<xs:attribute name="name" type="xs:string" use="required" />
|
||||
<xs:attribute name="class" type="orm:fqcn" use="required" />
|
||||
<xs:attribute name="class" type="orm:fqcn" use="optional" />
|
||||
<xs:attribute name="column-prefix" type="xs:string" use="optional" />
|
||||
<xs:attribute name="use-column-prefix" type="xs:boolean" default="true" use="optional" />
|
||||
</xs:complexType>
|
||||
|
||||
@@ -26,6 +26,7 @@ use Doctrine\Common\Annotations\CachedReader;
|
||||
use Doctrine\Common\Annotations\SimpleAnnotationReader;
|
||||
use Doctrine\Common\Cache\ArrayCache;
|
||||
use Doctrine\Common\Cache\Cache as CacheDriver;
|
||||
use Doctrine\Common\Cache\Psr6\CacheAdapter;
|
||||
use Doctrine\Common\Cache\Psr6\DoctrineProvider;
|
||||
use Doctrine\Common\Proxy\AbstractProxyFactory;
|
||||
use Doctrine\Deprecations\Deprecation;
|
||||
@@ -326,6 +327,7 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
);
|
||||
|
||||
$this->_attributes['metadataCacheImpl'] = $cacheImpl;
|
||||
$this->_attributes['metadataCache'] = CacheAdapter::wrap($cacheImpl);
|
||||
}
|
||||
|
||||
public function getMetadataCache(): ?CacheItemPoolInterface
|
||||
@@ -335,7 +337,8 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
|
||||
public function setMetadataCache(CacheItemPoolInterface $cache): void
|
||||
{
|
||||
$this->_attributes['metadataCache'] = $cache;
|
||||
$this->_attributes['metadataCache'] = $cache;
|
||||
$this->_attributes['metadataCacheImpl'] = DoctrineProvider::wrap($cache);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -430,16 +433,12 @@ class Configuration extends \Doctrine\DBAL\Configuration
|
||||
throw ORMException::proxyClassesAlwaysRegenerating();
|
||||
}
|
||||
|
||||
if ($this->getMetadataCache()) {
|
||||
return;
|
||||
if (! $this->getMetadataCache()) {
|
||||
throw ORMException::metadataCacheNotConfigured();
|
||||
}
|
||||
|
||||
$metadataCacheImpl = $this->getMetadataCacheImpl();
|
||||
|
||||
if (! $metadataCacheImpl) {
|
||||
throw ORMException::metadataCacheNotConfigured();
|
||||
}
|
||||
|
||||
if ($metadataCacheImpl instanceof ArrayCache) {
|
||||
throw ORMException::metadataCacheUsesNonPersistentCache($metadataCacheImpl);
|
||||
}
|
||||
|
||||
@@ -710,6 +710,7 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
* metadata of the class with the given name.
|
||||
*
|
||||
* @param string $entityName The name of the entity class the new instance is used for.
|
||||
* @psalm-param class-string<T> $entityName
|
||||
*/
|
||||
public function __construct($entityName, ?NamingStrategy $namingStrategy = null)
|
||||
{
|
||||
@@ -1467,10 +1468,6 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
$type = $this->reflClass->getProperty($mapping['fieldName'])->getType();
|
||||
|
||||
if ($type) {
|
||||
if (! isset($mapping['nullable'])) {
|
||||
$mapping['nullable'] = $type->allowsNull();
|
||||
}
|
||||
|
||||
if (
|
||||
! isset($mapping['type'])
|
||||
&& ($type instanceof ReflectionNamedType)
|
||||
@@ -1526,14 +1523,6 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
$mapping['targetEntity'] = $type->getName();
|
||||
}
|
||||
|
||||
if (isset($mapping['joinColumns'])) {
|
||||
foreach ($mapping['joinColumns'] as &$joinColumn) {
|
||||
if ($type->allowsNull() === false) {
|
||||
$joinColumn['nullable'] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $mapping;
|
||||
}
|
||||
|
||||
@@ -3604,9 +3593,16 @@ class ClassMetadataInfo implements ClassMetadata
|
||||
{
|
||||
$this->assertFieldNotMapped($mapping['fieldName']);
|
||||
|
||||
if (! isset($mapping['class']) && $this->isTypedProperty($mapping['fieldName'])) {
|
||||
$type = $this->reflClass->getProperty($mapping['fieldName'])->getType();
|
||||
if ($type instanceof ReflectionNamedType) {
|
||||
$mapping['class'] = $type->getName();
|
||||
}
|
||||
}
|
||||
|
||||
$this->embeddedClasses[$mapping['fieldName']] = [
|
||||
'class' => $this->fullyQualifiedClassName($mapping['class']),
|
||||
'columnPrefix' => $mapping['columnPrefix'],
|
||||
'columnPrefix' => $mapping['columnPrefix'] ?? null,
|
||||
'declaredField' => $mapping['declaredField'] ?? null,
|
||||
'originalField' => $mapping['originalField'] ?? null,
|
||||
];
|
||||
|
||||
@@ -57,8 +57,8 @@ final class Column implements Annotation
|
||||
/** @var bool */
|
||||
public $unique = false;
|
||||
|
||||
/** @var bool|null */
|
||||
public $nullable;
|
||||
/** @var bool */
|
||||
public $nullable = false;
|
||||
|
||||
/** @var array<string,mixed> */
|
||||
public $options = [];
|
||||
@@ -76,7 +76,7 @@ final class Column implements Annotation
|
||||
?int $precision = null,
|
||||
?int $scale = null,
|
||||
bool $unique = false,
|
||||
?bool $nullable = null,
|
||||
bool $nullable = false,
|
||||
array $options = [],
|
||||
?string $columnDefinition = null
|
||||
) {
|
||||
|
||||
@@ -324,7 +324,7 @@ class XmlDriver extends FileDriver
|
||||
|
||||
$mapping = [
|
||||
'fieldName' => (string) $embeddedMapping['name'],
|
||||
'class' => (string) $embeddedMapping['class'],
|
||||
'class' => isset($embeddedMapping['class']) ? (string) $embeddedMapping['class'] : null,
|
||||
'columnPrefix' => $useColumnPrefix ? $columnPrefix : false,
|
||||
];
|
||||
|
||||
|
||||
@@ -408,7 +408,7 @@ class YamlDriver extends FileDriver
|
||||
foreach ($element['embedded'] as $name => $embeddedMapping) {
|
||||
$mapping = [
|
||||
'fieldName' => $name,
|
||||
'class' => $embeddedMapping['class'],
|
||||
'class' => $embeddedMapping['class'] ?? null,
|
||||
'columnPrefix' => $embeddedMapping['columnPrefix'] ?? null,
|
||||
];
|
||||
$metadata->mapEmbedded($mapping);
|
||||
|
||||
@@ -31,16 +31,13 @@ use Doctrine\Common\Annotations\Annotation\NamedArgumentConstructor;
|
||||
#[Attribute(Attribute::TARGET_PROPERTY)]
|
||||
final class Embedded implements Annotation
|
||||
{
|
||||
/**
|
||||
* @Required
|
||||
* @var string
|
||||
*/
|
||||
/** @var string|null */
|
||||
public $class;
|
||||
|
||||
/** @var string|bool|null */
|
||||
public $columnPrefix;
|
||||
|
||||
public function __construct(string $class, $columnPrefix = null)
|
||||
public function __construct(?string $class = null, $columnPrefix = null)
|
||||
{
|
||||
$this->class = $class;
|
||||
$this->columnPrefix = $columnPrefix;
|
||||
|
||||
@@ -78,7 +78,6 @@ use Doctrine\ORM\Query\AST\UpdateStatement;
|
||||
use Doctrine\ORM\Query\AST\WhenClause;
|
||||
use Doctrine\ORM\Query\AST\WhereClause;
|
||||
use ReflectionClass;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
use function array_intersect;
|
||||
use function array_search;
|
||||
@@ -3543,7 +3542,7 @@ class Parser
|
||||
$functionName = strtolower($this->lexer->lookahead['value']);
|
||||
$functionClass = $this->em->getConfiguration()->getCustomNumericFunction($functionName);
|
||||
|
||||
Assert::notNull($functionClass);
|
||||
assert($functionClass !== null);
|
||||
|
||||
$function = is_string($functionClass)
|
||||
? new $functionClass($functionName)
|
||||
@@ -3584,7 +3583,7 @@ class Parser
|
||||
$functionName = $this->lexer->lookahead['value'];
|
||||
$functionClass = $this->em->getConfiguration()->getCustomDatetimeFunction($functionName);
|
||||
|
||||
Assert::notNull($functionClass);
|
||||
assert($functionClass !== null);
|
||||
|
||||
$function = is_string($functionClass)
|
||||
? new $functionClass($functionName)
|
||||
@@ -3626,7 +3625,7 @@ class Parser
|
||||
$functionName = $this->lexer->lookahead['value'];
|
||||
$functionClass = $this->em->getConfiguration()->getCustomStringFunction($functionName);
|
||||
|
||||
Assert::notNull($functionClass);
|
||||
assert($functionClass !== null);
|
||||
|
||||
$function = is_string($functionClass)
|
||||
? new $functionClass($functionName)
|
||||
|
||||
@@ -105,6 +105,7 @@ class ConvertDoctrine1Schema
|
||||
|
||||
/**
|
||||
* @param mixed[] $mappingInformation
|
||||
* @psalm-param class-string $className
|
||||
*/
|
||||
private function convertToClassMetadataInfo(
|
||||
string $className,
|
||||
|
||||
@@ -630,9 +630,13 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param ClassMetadata $class The class descriptor of the entity.
|
||||
* @param object $entity The entity for which to compute the changes.
|
||||
* @psalm-param ClassMetadata<T> $class
|
||||
* @psalm-param T $entity
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @template T of object
|
||||
*
|
||||
* @ignore
|
||||
*/
|
||||
public function computeChangeSet(ClassMetadata $class, $entity)
|
||||
@@ -959,6 +963,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
|
||||
/**
|
||||
* @param object $entity
|
||||
* @psalm-param ClassMetadata<T> $class
|
||||
* @psalm-param T $entity
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function persistNew(ClassMetadata $class, $entity): void
|
||||
{
|
||||
@@ -1017,11 +1025,14 @@ class UnitOfWork implements PropertyChangedListener
|
||||
*
|
||||
* @param ClassMetadata $class The class descriptor of the entity.
|
||||
* @param object $entity The entity for which to (re)calculate the change set.
|
||||
* @psalm-param ClassMetadata<T> $class
|
||||
* @psalm-param T $entity
|
||||
*
|
||||
* @return void
|
||||
*
|
||||
* @throws ORMInvalidArgumentException If the passed entity is not MANAGED.
|
||||
*
|
||||
* @template T of object
|
||||
* @ignore
|
||||
*/
|
||||
public function recomputeSingleEntityChangeSet(ClassMetadata $class, $entity)
|
||||
@@ -1144,6 +1155,10 @@ class UnitOfWork implements PropertyChangedListener
|
||||
|
||||
/**
|
||||
* @param object $entity
|
||||
* @psalm-param ClassMetadata<T> $class
|
||||
* @psalm-param T $entity
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function addToEntityIdentifiersAndEntityMap(
|
||||
ClassMetadata $class,
|
||||
@@ -2020,8 +2035,13 @@ class UnitOfWork implements PropertyChangedListener
|
||||
/**
|
||||
* @param object $entity
|
||||
* @param object $managedCopy
|
||||
* @psalm-param ClassMetadata<T> $class
|
||||
* @psalm-param T $entity
|
||||
* @psalm-param T $managedCopy
|
||||
*
|
||||
* @throws OptimisticLockException
|
||||
*
|
||||
* @template T of object
|
||||
*/
|
||||
private function ensureVersionMatch(
|
||||
ClassMetadata $class,
|
||||
|
||||
@@ -557,7 +557,7 @@ parameters:
|
||||
|
||||
-
|
||||
message: "#^Call to an undefined method ReflectionProperty\\:\\:getType\\(\\)\\.$#"
|
||||
count: 2
|
||||
count: 3
|
||||
path: lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php
|
||||
|
||||
-
|
||||
@@ -1457,7 +1457,7 @@ parameters:
|
||||
path: lib/Doctrine/ORM/Query/Parser.php
|
||||
|
||||
-
|
||||
message: "#^Parameter \\#1 \\$function of function call_user_func expects callable\\(\\)\\: mixed, null given\\.$#"
|
||||
message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#"
|
||||
count: 3
|
||||
path: lib/Doctrine/ORM/Query/Parser.php
|
||||
|
||||
|
||||
@@ -1125,9 +1125,7 @@
|
||||
<code>$table</code>
|
||||
<code>$tableGeneratorDefinition</code>
|
||||
</PropertyNotSetInConstructor>
|
||||
<PropertyTypeCoercion occurrences="13">
|
||||
<code>$entityName</code>
|
||||
<code>$entityName</code>
|
||||
<PropertyTypeCoercion occurrences="11">
|
||||
<code>$this->entityListeners</code>
|
||||
<code>$this->fieldMappings</code>
|
||||
<code>$this->fullyQualifiedClassName($repositoryClassName)</code>
|
||||
|
||||
18
tests/Doctrine/Tests/Models/TypedProperties/Contact.php
Normal file
18
tests/Doctrine/Tests/Models/TypedProperties/Contact.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Tests\Models\TypedProperties;
|
||||
|
||||
use Doctrine\ORM\Mapping as ORM;
|
||||
|
||||
/**
|
||||
* @ORM\Embeddable()
|
||||
*/
|
||||
#[ORM\Embeddable]
|
||||
class Contact
|
||||
{
|
||||
/** @Column() */
|
||||
#[ORM\Column]
|
||||
public ?string $email = null;
|
||||
}
|
||||
@@ -24,6 +24,7 @@ class UserTyped
|
||||
*/
|
||||
#[ORM\Id, ORM\Column, ORM\GeneratedValue]
|
||||
public int $id;
|
||||
|
||||
/** @Column(length=50) */
|
||||
#[ORM\Column(length: 50)]
|
||||
public ?string $status;
|
||||
@@ -67,6 +68,10 @@ class UserTyped
|
||||
#[ORM\ManyToOne]
|
||||
public ?CmsEmail $mainEmail;
|
||||
|
||||
/** @Embedded */
|
||||
#[ORM\Embedded]
|
||||
public ?Contact $contact = null;
|
||||
|
||||
public static function loadMetadata(ClassMetadataInfo $metadata): void
|
||||
{
|
||||
$metadata->setInheritanceType(ClassMetadataInfo::INHERITANCE_TYPE_NONE);
|
||||
@@ -131,5 +136,7 @@ class UserTyped
|
||||
$metadata->mapManyToOne(
|
||||
['fieldName' => 'mainEmail']
|
||||
);
|
||||
|
||||
$metadata->mapEmbedded(['fieldName' => 'contact']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@ class ConfigurationTest extends DoctrineTestCase
|
||||
$queryCacheImpl = $this->createMock(Cache::class);
|
||||
$this->configuration->setMetadataCacheImpl($queryCacheImpl);
|
||||
$this->assertSame($queryCacheImpl, $this->configuration->getMetadataCacheImpl());
|
||||
$this->assertNotNull($this->configuration->getMetadataCache());
|
||||
}
|
||||
|
||||
public function testSetGetMetadataCache(): void
|
||||
@@ -141,6 +142,7 @@ class ConfigurationTest extends DoctrineTestCase
|
||||
$cache = $this->createStub(CacheItemPoolInterface::class);
|
||||
$this->configuration->setMetadataCache($cache);
|
||||
$this->assertSame($cache, $this->configuration->getMetadataCache());
|
||||
$this->assertNotNull($this->configuration->getMetadataCacheImpl());
|
||||
}
|
||||
|
||||
public function testAddGetNamedQuery(): void
|
||||
|
||||
@@ -42,6 +42,7 @@ use Doctrine\Tests\Models\DDC889\DDC889Class;
|
||||
use Doctrine\Tests\Models\DDC889\DDC889Entity;
|
||||
use Doctrine\Tests\Models\DDC964\DDC964Admin;
|
||||
use Doctrine\Tests\Models\DDC964\DDC964Guest;
|
||||
use Doctrine\Tests\Models\TypedProperties\Contact;
|
||||
use Doctrine\Tests\Models\TypedProperties\UserTyped;
|
||||
use Doctrine\Tests\OrmTestCase;
|
||||
|
||||
@@ -265,24 +266,6 @@ abstract class AbstractMappingDriverTest extends OrmTestCase
|
||||
return $class;
|
||||
}
|
||||
|
||||
public function testFieldIsNullableByType(): void
|
||||
{
|
||||
if (PHP_VERSION_ID < 70400) {
|
||||
$this->markTestSkipped('requies PHP 7.4');
|
||||
}
|
||||
|
||||
$class = $this->createClassMetadata(UserTyped::class);
|
||||
|
||||
// Explicit Nullable
|
||||
$this->assertTrue($class->isNullable('status'));
|
||||
|
||||
// Explicit Not Nullable
|
||||
$this->assertFalse($class->isNullable('username'));
|
||||
|
||||
$this->assertEquals(CmsEmail::class, $class->getAssociationMapping('email')['targetEntity']);
|
||||
$this->assertEquals(CmsEmail::class, $class->getAssociationMapping('mainEmail')['targetEntity']);
|
||||
}
|
||||
|
||||
public function testFieldTypeFromReflection(): void
|
||||
{
|
||||
if (PHP_VERSION_ID < 70400) {
|
||||
@@ -299,6 +282,10 @@ abstract class AbstractMappingDriverTest extends OrmTestCase
|
||||
$this->assertEquals('json', $class->getTypeOfField('array'));
|
||||
$this->assertEquals('boolean', $class->getTypeOfField('boolean'));
|
||||
$this->assertEquals('float', $class->getTypeOfField('float'));
|
||||
|
||||
$this->assertEquals(CmsEmail::class, $class->getAssociationMapping('email')['targetEntity']);
|
||||
$this->assertEquals(CmsEmail::class, $class->getAssociationMapping('mainEmail')['targetEntity']);
|
||||
$this->assertEquals(Contact::class, $class->embeddedClasses['contact']['class']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -120,19 +120,14 @@ class ClassMetadataTest extends OrmTestCase
|
||||
$cm = new ClassMetadata(TypedProperties\UserTyped::class);
|
||||
$cm->initializeReflection(new RuntimeReflectionService());
|
||||
|
||||
// Explicit Nullable
|
||||
$cm->mapField(['fieldName' => 'status', 'length' => 50]);
|
||||
$this->assertTrue($cm->isNullable('status'));
|
||||
|
||||
// Explicit Not Nullable
|
||||
$cm->mapField(['fieldName' => 'username', 'length' => 50]);
|
||||
$this->assertFalse($cm->isNullable('username'));
|
||||
|
||||
$cm->mapOneToOne(['fieldName' => 'email', 'joinColumns' => [[]]]);
|
||||
$this->assertEquals(CmsEmail::class, $cm->getAssociationMapping('email')['targetEntity']);
|
||||
|
||||
$cm->mapManyToOne(['fieldName' => 'mainEmail']);
|
||||
$this->assertEquals(CmsEmail::class, $cm->getAssociationMapping('mainEmail')['targetEntity']);
|
||||
|
||||
$cm->mapEmbedded(['fieldName' => 'contact']);
|
||||
$this->assertEquals(TypedProperties\Contact::class, $cm->embeddedClasses['contact']['class']);
|
||||
}
|
||||
|
||||
public function testFieldTypeFromReflection(): void
|
||||
|
||||
@@ -61,3 +61,5 @@ $metadata->mapOneToOne(
|
||||
$metadata->mapManyToOne(
|
||||
['fieldName' => 'mainEmail']
|
||||
);
|
||||
|
||||
$metadata->mapEmbedded(['fieldName' => 'contact']);
|
||||
|
||||
@@ -25,5 +25,7 @@
|
||||
</one-to-one>
|
||||
|
||||
<many-to-one field="mainEmail"/>
|
||||
|
||||
<embedded name="contact" />
|
||||
</entity>
|
||||
</doctrine-mapping>
|
||||
|
||||
@@ -24,3 +24,5 @@ Doctrine\Tests\Models\TypedProperties\UserTyped:
|
||||
joinColumn: []
|
||||
manyToOne:
|
||||
mainEmail: []
|
||||
embedded:
|
||||
contact: ~
|
||||
|
||||
Reference in New Issue
Block a user