CakePHP3.4:不理解保存 belongsToMany 关联的错误

CakePHP3.4: don't understand error saving a belongsToMany association

我尝试在表单中输入一个 belongsToMany 关联,但是一个非常特殊的关联描述。
因为我的实体 Site 可以将语言用于 2 种不同的用途,所以我使用 2 个连接表。
所以架构如下

Relationship                        Join Table Fields
Sites belongsToMany Vislanguages    sites_vislanguages.id, sites_vislanguages.language_id, sites_vislanguages.site_id
Relationship                        Join Table Fields
Sites belongsToMany Reclanguages    sites_reclanguages.id, sites_reclanguages.language_id, sites_reclanguages.site_id

所以 Table class 是:

class VislanguagesTable extends Table {

    public function initialize(array $config) {
        parent::initialize($config);

        $this->table('languages');
        $this->displayField('name_fr');
        $this->primaryKey('id');

        $this->belongsToMany('Sites', [
            'foreignKey' => 'language_id',
            'targetForeignKey' => 'site_id',
            'joinTable' => 'sites_vislanguages',
        ]);

    }
}

class SitesTable extends Table {

public function initialize(array $config) {
    parent::initialize($config);

    $this->belongsToMany('Reclanguages', [
        'joinTable' => 'sites_reclanguages',
        'className' => 'Languages',
        'propertyName' => 'reclanguages'
    ]);

    $this->belongsToMany('Vislanguages', [
        'joinTable' => 'sites_vislanguages',
        'className' => 'Languages',
        'propertyName' => 'vislanguages'
    ]);

}

class SitesVislanguagesTable 扩展 Table {

public function initialize(array $config) {
    parent::initialize($config);

    $this->table('sites_vislanguages');
    $this->displayField('id');
    $this->primaryKey('id');

    $this->belongsTo('Sites', [
        'foreignKey' => 'site_id',
    ]);
    $this->belongsTo('Languages', [
        'foreignKey' => 'language_id',
    ]);
}

我当然有addedit形式的问题,但我这里以edit为例。 如果我find()一个现成的site,数据结构是:

object(App\Model\Entity\Site) {

    'id' => (int) 23098,
    'Vislanguages' => [
        (int) 0 => object(App\Model\Entity\Language) {

            'id' => (int) 1,
            '_joinData' => object(App\Model\Entity\SitesVislanguage) {

                'id' => (int) 4409,
                'site_id' => (int) 23098,
                'language_id' => (int) 1,
                ...,
                '[repository]' => 'SitesVislanguages'

            },
            ...,
            '[repository]' => 'Vislanguages'

        },
        (int) 1 => object(App\Model\Entity\Language) {

            'id' => (int) 9,
            '_joinData' => object(App\Model\Entity\SitesVislanguage) {

                'id' => (int) 4410,
                'site_id' => (int) 23098,
                'language_id' => (int) 9,
                ...,
                '[repository]' => 'SitesVislanguages'

            },
            ...,
            '[repository]' => 'Vislanguages'

        }
    ],
    ...,
    '[repository]' => 'Sites'

}

而我对应的ctp文件是:

<?= $this->Form->control('vislanguages._ids', ['options' => $languages, 'label' => __('Spoken languages:'), 'multiple' => true]); ?>

在输入中正确预选了语言。 如果我不做任何修改提交,打补丁的实体是:

对象(App\Model\Entity\Site) {

'id' => (int) 23098,
...,
'vislanguages' => [
    (int) 0 => object(App\Model\Entity\Language) {

        'id' => (int) 1,
        ...,
        '[repository]' => 'Vislanguages'

    },
    (int) 1 => object(App\Model\Entity\Language) {

        'id' => (int) 9,
        ...,
        '[repository]' => 'Vislanguages'

    }
],
'[repository]' => 'Sites'

}

这似乎是正确的,但当我保存它时,出现以下错误:

Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'vislanguage_id' in 'where clause' 

查询是:

(SELECT SitesVislanguages.id AS `SitesVislanguages__id`, SitesVislanguages.site_id AS `SitesVislanguages__site_id`, SitesVislanguages.language_id AS `SitesVislanguages__language_id` FROM sites_vislanguages SitesVislanguages WHERE (site_id = :c0 AND vislanguage_id = :c1))
UNION (SELECT SitesVislanguages.id AS `SitesVislanguages__id`, SitesVislanguages.site_id AS `SitesVislanguages__site_id`, SitesVislanguages.language_id AS `SitesVislanguages__language_id` FROM sites_vislanguages SitesVislanguages WHERE (site_id = :c2 AND vislanguage_id = :c3))

为什么我们在 WHERE 子句中看到 vislanguage_id 而在 SELECT 子句中却正确地考虑了 language_id

同时,这里的UNION我也不是很懂

为了让它工作,我必须指定 targetForeignKey:

class SitesTable extends Table {

public function initialize(array $config) {
    parent::initialize($config);

    $this->belongsToMany('Reclanguages', [
        'targetForeignKey' => 'language_id,
        'joinTable' => 'sites_reclanguages',
        'className' => 'Languages',
        'propertyName' => 'reclanguages'
    ]);

    $this->belongsToMany('Vislanguages', [
        'targetForeignKey' => 'language_id,
        'joinTable' => 'sites_vislanguages',
        'className' => 'Languages',
        'propertyName' => 'vislanguages'
    ]);

}