Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Commit order issue #5538

Closed
kilhage opened this issue Dec 8, 2015 · 5 comments · Fixed by #10547
Closed

Commit order issue #5538

kilhage opened this issue Dec 8, 2015 · 5 comments · Fixed by #10547

Comments

@kilhage
Copy link

kilhage commented Dec 8, 2015

I have a very annoying issue regarding the commit order calculated by the UnitOfWork & CommitOrderCalculator components.

I have two entities, the important parts in this case looks like this:

/**
 * @ORM\Entity()
 */
class Hotel
{
    /**
     * @var HotelImage
     *
     * @ORM\ManyToOne(targetEntity="HotelImage", inversedBy="thumbnailHotels")
     * @ORM\JoinColumn(name="thumbnail_id", referencedColumnName="id", nullable=true, onDelete="SET NULL")
     */
    private $thumbnail;

    /**
     * @var ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="HotelImage", mappedBy="hotel")
     */
    private $images;
}
/**
 * @ORM\Entity()
 */
class HotelImage
{
    /**
     * @var Hotel
     *
     * @Assert\NotBlank()
     * @ORM\ManyToOne(targetEntity="Hotel", inversedBy="images")
     * @ORM\JoinColumn(name="hotel_id", referencedColumnName="id", onDelete="CASCADE", nullable=false)
     */
    private $hotel;

    /**
     * @var ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="Hotel", mappedBy="thumbnail")
     */
    private $thumbnailHotels;
}

The code snippet I have problem when looks like this:

$country = $countryRepo->findByName('Sweden');
$city = $cityRepo->findByCountryAndName($country, 'Stockholm');

$hotel = $hotelRepo->findByCityAndName($city, 'Radisson Blu Waterfront Stockholm');

$image = new HotelImage();
$image->setHotel($hotel);
$hotel->addImage($image);
$em->persist($image);

$hotel2 = new Hotel();
$hotel2->setCity($city);
$hotel2->setName('xxxxxxx');
$em->persist($hotel2);

$image = new HotelImage();
$image->setHotel($hotel2);
$hotel2->addImage($image);
$em->persist($image);

$em->flush();

Then the following exception will be thrown:

  [Doctrine\DBAL\Driver\PDOException]
  SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'hotel_id' cannot be null

When looking at the sql statements executed I see these in the logs:

[2015-12-08 21:13:57] doctrine.DEBUG: INSERT INTO hotel_images (file_name, mime_type, url, code, created, updated, supplier_id, hotel_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?) {"1":null,"2":null,"3":null,"4":null,"5":"2015-12-08 21:13:56","6":"2015-12-08 21:13:56","7":null,"8":628550}
[2015-12-08 21:13:57] doctrine.DEBUG: INSERT INTO hotel_images (file_name, mime_type, url, code, created, updated, supplier_id, hotel_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?) {"1":null,"2":null,"3":null,"4":null,"5":"2015-12-08 21:13:56","6":"2015-12-08 21:13:56","7":null,"8":null}

If I instead run the following snippet:

$country = $countryRepo->findByName('Sweden');
$city = $cityRepo->findByCountryAndName($country, 'Stockholm');

$hotel2 = new Hotel();
$hotel2->setCity($city);
$hotel2->setName('xxxxxxx');
$em->persist($hotel2);

$image = new HotelImage();
$image->setHotel($hotel2);
$hotel2->addImage($image);
$em->persist($image);

$em->flush();
[2015-12-08 21:18:00] doctrine.DEBUG: INSERT INTO hotels (type, latitude, longitude, rating, user_score, number_of_reviews, phone_number, fax, url, check_in_time, check_out_time, number_of_rooms, street, postal_code, certified, certification_rating, center_distance, name, created, updated, thumbnail_id, hotel_chain_id, address_id, coordinates_id, city_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) {"1":null,"2":null,"3":null,"4":null,"5":0,"6":0,"7":null,"8":null,"9":null,"10":null,"11":null,"12":null,"13":null,"14":null,"15":false,"16":null,"17":null,"18":"xxxxxxx","19":"2015-12-08 21:18:00","20":"2015-12-08 21:18:00","21":null,"22":null,"23":null,"24":null,"25":2535}
[2015-12-08 21:18:00] doctrine.DEBUG: INSERT INTO hotel_images (file_name, mime_type, url, code, created, updated, supplier_id, hotel_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?) {"1":null,"2":null,"3":null,"4":null,"5":"2015-12-08 21:18:00","6":"2015-12-08 21:18:00","7":null,"8":642815}

The error occurs becouse depending on what entity gets persisted first, the \Doctrine\ORM\UnitOfWork::getCommitOrder will build commit order differently because the two entities are dependent of each other, but since the thumbnail_id is nullable this should still work..

One solution to this would of course be a different approach to the thumbnails but I'd stil expect the above test cases not to throw errors and the commit order to be consistent.

Please suggest a way around this without adding extra flushes, or change the order I persist the objects. I have a number of use cases in the project where this is used where I need to persist the objects in the order as in the test cases and can't add flushes because of performance reasons.

Any help is appreciated, thanks.

@guilhermeblanco
Copy link
Member

Which version are you using? I have fixed this problem on master (aka. 2.6.0-dev)

@kilhage
Copy link
Author

kilhage commented Dec 8, 2015

I'm using 2.5.2, any plans of cherry picking this fix into 2.5.3 or do we have to wait until 2.6? When is this scheduled to be release?

I can verify that this problem is fixed in master!

@Ocramius
Copy link
Member

Ocramius commented Dec 9, 2015

In order to release 2.6, we still need to correct doctrine/data-fixtures#212 :-(

@mpdude
Copy link
Contributor

mpdude commented Feb 20, 2023

@kilhage it sounds as if this has been resolved, can you confirm that?

@mpdude
Copy link
Contributor

mpdude commented Feb 27, 2023

Your description is incomplete, for example it does not deal with the thumbnail

@greg0ire greg0ire closed this as completed Aug 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants