Door
Erik Rijk
op 18-05-2014 16:53
gewijzigd op 18-05-2014 17:36
2.088 views
Ik heb 3 tabellen:
* Travel
* Youtube
* rel_travel_youtube.
1 reis kan meerdere youtube filmps hebben en 1 film kan bij meerdere reizen horen.
Via de cli heb ik de 2 entiteiten gekregen:
* Travel
* Youtube
Er is dus geen entiteit van de koppeltabel aanwezig.
Beide kolommen binnen de koppeltabel zijn gedfineerd als primary key(s).
Ik loop door een feed heen en per element insert ik de data.
Wanneer een video key al bestaat, krijg ik netjes de melding terug dat de waarde al voorkomt. ( unique ), maar dan wil ik alsnog een record in de koppeltabel inschieten.. Ik krijg het maar niet voor elkaar.
Mee eens.. Maar ik schiet het record ook niet in om het moment dat ik resultaat krijg op mn findOneBy select.
Ik wil een nieuw record in rel_travel_youtube, dat wel.
Omdat ze een relatie met elkaar hebben, zal de insert waarschijnlijk wel dubbel uitgevoerd worden met als resultaat een duplicate entry..
Het gaat nu wel om deze trouwens: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1XHA0t0zHFo' for key 'video'
Je kunt geen extra records in de koppeltabel invoegen. En als je het wel doet/kunt dan is het geen koppeltabel meer. Je zou er dan een entity van moeten maken.
Waarom denk je de hele tijd aan de koppeltabel terwijl je met doctrine hier totaal geen omkijken naar hebt?
Toevoeging op 18/05/2014 23:18:03:
Ga je nu zelf die koppeltabel handmatig zitten veranderen?
De relaties zoals ze zijn staan hierboven vermeld.
Ik heb de entiteiten laten genereren dmv: orm:convert-mapping. Hierdoor het ik de beschikking over de entiteiten: Youtube & Travel.
Als ik de youtube entiteit vul, en deze toevoeg aan Travel dmv: $oTravel->addYoutube( $oYoutube ), wordt deze geplaatst in de youtube tabel en is er een record bijgekomen in de rel_travel_youtube tabel.
So far so good. Hopelijk voor jullie ook nog helder.
de kolom: video, is uniek. En bij een een volgende keer dat ik een record wil inschieten met dezelfde video key, krijg ik een error dat het record al bestaat, wat ook logisch is.
Maar ik wil het ID van dat record gebruiken, om in rel_travel_youtube een nieuw record te maken.
Nou leg je het heel helder uit allemaal maar ik mis nog steeds de reden WAAROM je een record wilt maken in de koppeltabel (rel_travel_youtube).
Volgens mij is het antwoord dat je één film aan meerdere reizen kunt koppelen.
Je hoeft met doctrine nooit en te nimmer eigenhandig aan een koppeltabel te knoeien.
Wat jij doet zoals je het verteld: een record proberen toe te voegen aan de tabel youtube en afwachten of er een foutmelding komt. Draai die gedachte nou eens om en doe dan dit:
... ->findOneBy( array( 'video' => $youtubeCode )
Er kunnen nu twee dingen gebeuren: Je krijgt een entity terug met alle velden ingevuld van het gevonden record OF je krijgt een NULL terug als de youtube-code dus niet in de database voorkomt.
Vervolgens is het eigenlijk heel simpel:
Indien NULL: Creëer een nieuwe youtube entity, roep alle setters aan om de properties de juiste waarden te geven en roep addTravel aan om aan de youtube entity een travel te hangen. (welke je al in je database zou moeten hebben staan).
Indien je een entity terugkrijgt:
Hoef je enkel de addTravel aan te roepen. Immers het record bestaat al in de database maar je wilt een extra record in de koppeltabel.
Wordt er door de addYoutube() functie niet geprobeerd om het record in in de youtube tabel in te schieten?
Ik kan niks anders bedenken
Toevoeging op 19/05/2014 19:04:49:
Als ik aangeef dat de kolom 'video' niet uniek is, krijg ik allemaal record met dezelfde waarde in de kolom, maar in de koppeltabel gaat het wel automatisch goed.
Als ik aangeef dat de kolom 'video' niet uniek is, krijg ik allemaal record met dezelfde waarde in de kolom, maar in de koppeltabel gaat het wel automatisch goed.
Dan gaat er nog iets mis met het persisten naar je database. Je probeert een bestaande entity nogmaals te INSERTEN
Dit heb ik nu. Klein deel in commentaar.. Ik krijg het niet voor elkaar :-/ Alle mogelijke situaties hebben zich voorgedaan tijdens mn geknutsel, behalve het geen wat ik graag wil :)
Op basis van het geheel.. Wat raad je aan?
<?php
public function indexAction()
{
$oObjectManager = $this->getServiceLocator()->get( 'Doctrine\ORM\EntityManager' );
$oTravel = new Travel();
$oXmlReader = new \XMLReader();
foreach( $this->aXmlFiles as $sFilename )
{
$oXmlReader->open( $sFilename );
public function __construct() {
$this->movies = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* @param string $title
* @return Travel
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* @return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Add movies
*
* @param \FrankBeen\MainBundle\Entity\Movie $movies
* @return Travel
*/
public function addMovie(\FrankBeen\MainBundle\Entity\Movie $movies)
{
$this->movies[] = $movies;
return $this;
}
/**
* Remove movies
*
* @param \FrankBeen\MainBundle\Entity\Movie $movies
*/
public function removeMovie(\FrankBeen\MainBundle\Entity\Movie $movies)
{
$this->movies->removeElement($movies);
}
/**
* Get movies
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getMovies()
{
return $this->movies;
}
}
?>
Controller:
<?php
namespace FrankBeen\MainBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction($name)
{
$video = 'v=g_r4a-DXA7c';
$em = $this->getDoctrine()->getManager();
$movie = $em->getRepository('MainBundle:Movie')->findOneBy(array('video' => $video));
if($movie == NULL)
{
$movie = new \FrankBeen\MainBundle\Entity\Movie();
$movie->setVideo('v=g_r4a-DXA7c');
$movie->setTitle('PHP contactformulier en PHPMailer');
$em->persist($movie);
}
$travel = new \FrankBeen\MainBundle\Entity\Travel();
$travel->setTitle('travel A');
$travel->addMovie($movie);
$em->persist($travel);
$travel2 = new \FrankBeen\MainBundle\Entity\Travel(); // <-- MOEST ECHT EEN NEW Travel() MAKEN!!!!
$travel2->setTitle('travel B');
$travel2->addMovie($movie);
$em->persist($travel2);
$em->flush();