Skip to content

XML mapping doesn't take account of the attribute nullable for embedded document #2295

Closed
@wuchen90

Description

@wuchen90

Bug Report

Q A
BC Break no
Version 2.2.0

Summary

I use XML to map the documents.
When I set the attribute nullable=true to a property, which is an embedded document (embed-*), the ClassMetadata resulted always set this property to ClassMetadata->isNullable() === false.
By the way, mapping with annotations works well.

Here is an example of the mapping:

<document name="Model\Cart" collection="carts">
        <embed-one field="shippingAddress" target-document="Model\ShippingAddress" nullable="true"/>

Current behavior

Whatever the attribute nullable is, when it's set to an embedded document property, the ClassMetadata->isNullable() always returns false.
For annotation mapping, there is no problem because all the metadata provided in annotations are merged to build the ClassMetadata.
But for XML, the metadata are built attribute by attribute and there is no part dealing with nullable.
See

private function addEmbedMapping(ClassMetadata $class, SimpleXMLElement $embed, string $type): void
{
$attributes = $embed->attributes();
$defaultStrategy = $type === 'one' ? ClassMetadata::STORAGE_STRATEGY_SET : CollectionHelper::DEFAULT_STRATEGY;
$mapping = [
'type' => $type,
'embedded' => true,
'targetDocument' => isset($attributes['target-document']) ? (string) $attributes['target-document'] : null,
'collectionClass' => isset($attributes['collection-class']) ? (string) $attributes['collection-class'] : null,
'name' => (string) $attributes['field'],
'strategy' => (string) ($attributes['strategy'] ?? $defaultStrategy),
];
if (isset($attributes['field-name'])) {
$mapping['fieldName'] = (string) $attributes['field-name'];
}
if (isset($embed->{'discriminator-field'})) {
$attr = $embed->{'discriminator-field'};
$mapping['discriminatorField'] = (string) $attr['name'];
}
if (isset($embed->{'discriminator-map'})) {
foreach ($embed->{'discriminator-map'}->{'discriminator-mapping'} as $discriminatorMapping) {
$attr = $discriminatorMapping->attributes();
$mapping['discriminatorMap'][(string) $attr['value']] = (string) $attr['class'];
}
}
if (isset($embed->{'default-discriminator-value'})) {
$mapping['defaultDiscriminatorValue'] = (string) $embed->{'default-discriminator-value'}['value'];
}
if (isset($attributes['not-saved'])) {
$mapping['notSaved'] = ((string) $attributes['not-saved'] === 'true');
}
if (isset($attributes['also-load'])) {
$mapping['alsoLoadFields'] = explode(',', $attributes['also-load']);
}
$this->addFieldMapping($class, $mapping);
}

Expected behavior

If the nullable attribute is set to true to an embedded document property, the ClassMetadata->isNullable() must returns true.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions