Доктрина 2 спасения сущности с возможными отношениями

0

Я пытаюсь сохранить Entity, который может или не может существовать и может иметь или не иметь одно или два отношения (код ниже). Мой текущий метод приводит к ошибкам, я вполне уверен, что могу придумать некоторые обходные пути/хаки самостоятельно, но меня интересует правильный "официальный" способ сделать это.

Что я сейчас пытаюсь сделать:

$entity = new myEntity();
if ( !empty($id) )
{
    $entity->setId($id);
}
$entity->setLocationId($relation_id); //may or may not be null, if not null it always an already existing location entry in a different table, i.e. not a new
$entity = $entity_manager->merge($entity);
$entity_manager->flush();

В настоящее время Doctrine жалуется на то, что Location является новым Entity без идентификатора, и политика не позволяет автоматически генерировать идентификаторы. Политика действительно такова, но я вообще не добавляю объект местоположения, я использую метод setLocationId(), созданный автоматически, который добавляет точно существующий идентификатор местоположения, поэтому я немного озадачен.

edit: Я получаю ошибку doctrine, когда идентификатор местоположения не является нулевым, а реальным, существующим (в db) идентификатором местоположения.

И модель:

Location:
    type: entity
    table: locationstable
    id:
        my-id-column:
            type: string
    fields:
        some fields
    oneToMany:
        myEntities:
            targetEntity: myEntity
            mappedBy: location
            cascade: ["persist", "merge"]
Теги:
doctrine2

2 ответа

1
Лучший ответ

Если вы собираетесь использовать Doctrine 2 ORM, вам действительно нужно использовать его, как было разработано. Это означает работу с объектами, а не с идентификаторами. Если вам не нравится этот подход, переключитесь на какую-то активную реализацию записи.

//For your case, start by seeing if there is an existing entity:
// This eliminates all the merge nonsense
$entity = $entityManager->getRepository('EntityClassName')->find($entityId);
if (!$entity)
{
    $entity = new Entity();

    /* Only do this is you are not autogenerating id's
     * However, it does raise the question of how you know what the id should be if the entity
     * if the entity does not yet exist?
     */
    $entity->setId($id);

    // Persist the new entity
    $entityManager->persist($entity);
}

// Now get a reference to the location object which saves loading the entire location
// which optimizes things a tiny (probably unnoticeable) bit
$location = $entityManager->getReference('LocationClassName',$locationId);
$entity->setLocation($location);

// And flush changes
$entityManager->flush();

И снова, если вы считаете, что это слишком сложно или слишком много запросов, тогда не используйте Doctrine 2. Вы будете бороться с ним постоянно. На практике Doctrine 2 получается неплохо. Никакой реальной необходимости беспокоиться о микро-оптимизации.

  • 0
    Спасибо, getReference (), вероятно, именно то, что мне нужно! Также спасибо за совет по бессмысленному слиянию :) Использование Doctrine 2 по назначению было тем, о чем весь этот вопрос был. Мне просто нужно узнать, что предназначено, а что нет. Что касается идентификатора, я знаю, каким должен быть идентификатор, потому что я их генерирую.
0

Попробуйте найти запись местоположения и добавить к объекту:

$entity = new myEntity();
if ( !empty($id) )
{
    $entity->setId($id);
}
//$entity->setLocationId($relation_id); //may or may not be null, if not null it always an already existing 

$location = $locationRepository->find($relation_id);
$entity->setLocation($location);

location entry in a different table, i.e. not a new
$entity = $entity_manager->merge($entity);
$entity_manager->flush();
  • 0
    Это может сработать, но это как минимум два запроса к базе данных для простой операции сохранения, разве нет лучшего способа?
  • 0
    управлять вашей проблемой с помощью cascade операции может быть дороже: посмотрите на этот документ . Кстати, мой выбор - поиск по идентификатору таблицы, это не займет больше времени

Ещё вопросы

Сообщество Overcoder
Наверх
Меню