1

I am trying to map a relationship between 2 MySQL tables in Doctrine 2. My owning entity is 'Campaign', it joins to 'Channel'.

When a campaign record is saved, it must contain a channel id. When a campaign is retrieved I would like to use this id to join to channel and display the channel name (from the channel table). I believe this is a one-to-one unidirectional relationship, please correct me if I'm wrong.

table relationship

I have specified the mapping using Doctrine 2 XML as follows:

    <one-to-one field="channelId" target-entity="Channel" fetch="EAGER">
        <join-column name="channel_id" referenced-column-name="id" />
    </one-to-one>

When populating the campaign entity and attempting to persist it, I am getting the following error.

A new entity was found through a relationship that was not configured to cascade persist operations: Mvc\Entity\Channel@0000000034b3dcd500000000cc77faae. Explicitly persist the new entity or configure cascading persist operations on the relationship.

How should this persist be specified, I do not want to modify or save the channel entity. I have studied that Doctrine 2 documentation on 'Association Mapping' but I cannot understand how this is possible.

Thank you.

Richard
  • 422
  • 7
  • 17

2 Answers2

2

When you persist an object, you need to make sure that all associated objects are also persisted. In this case, you are creating a Campaign and associating it with a Channel. If the Channel object is not already persisted, you need to do so before calling flush or put a persist cascade on the relationship. Here are your two options:

1) In your code, when you persist Campaign, also explicitly persist the Channel.

$em->perist($campaign);
$em->persist($campaign->getChannel());

2) Put a persist cascade on Campaign::channel. This will automatically persist the Channel object when it is associated with a Campaign. I don't know the exact syntax in XML, but try

<one-to-one field="channelId" target-entity="Channel" fetch="EAGER">
    <join-column name="channel_id" referenced-column-name="id" />
    <cascade><cascade-persist /></cascade>
</one-to-one>
Michael Ridgway
  • 5,259
  • 1
  • 16
  • 6
1

Found someone with a similar problem here. The problem was that there were 2 references in the Campaign XML mapping to the Channels table (channel_id and channel_name). Only the channel_id was required and the channel entity must be created and assigned to the campaign entity before the campaign entity can be persisted.

Strangely I did not need to explicitly persist the Channel entity separately. My Campaign XML mapping looks like this:

<one-to-one field="channelId" target-entity="ToastChannels" fetch="EAGER">
 <join-column name="channel_id" referenced-column-name="id" />
</one-to-one>

The assignment looks like this:

    $channelEntity = $this->_channelsDao->disableCache()->findObject($channelId]);
    $campaignEntity->setChannel($channelEntity);
    return $this->_campaignDao->save($campaignEntity);

At the DB level, only a Channel ID is being stored to the Campaign table as expected. I am still unsure as to how this is possible since no persistence rule has been specified.

Richard
  • 422
  • 7
  • 17