doucan957495 2014-05-22 17:41
浏览 39
已采纳

一对多的Doctrine关系在Symfony2应用程序中不显示多个条目

Background

I am running a Symfony2 application for a client that tracks AEDs (defibrillators), their maintenance records, and persons responsible for their maintenance. I'm in a beta launch and have run into an issue with a one-to-many bidirectional relationship achieved with Doctrine.

The project was a conversion from a previous schema on a custom-developed framework. This means I used

Schema

The relationship structure is a "top-down approach" where the AEDs are organized by the following:

Municipalities
    one-to-many-> Organizations
        one-to-many-> Locations
            one-to-many-> AEDs
                one-to-many-> Monthly Check Logs
                one-to-many-> Maintenance Records
            one-to-many-> Persons
                one-to-many-> Contact Entries

(This is simplified but should give you enough context for the problem I'm having.)

The Problem

I am showing a "User Profile" where all of their associated contact entries are listed in a table. The problem is when a new entry is added, only (the newest) one shows up in the table. The others are still stored in the database but hidden for some reason.

The desired

Debugging Steps

I cloned the production database into my staging environment and replicated the problem.

I tried forcing the fetch mode to EAGER and still had the same problem.

I checked the length of person.contacts and it outputted a value of 1.

I tried taking the runnable eager query directly into the database (as follows) and had a result of multiple entries (greater than 1):

SELECT 
  t0.table_id AS table_id1, 
  t0.ref_id AS ref_id2, 
  t0.person_id AS person_id3, 
  t0.contact_type AS contact_type4, 
  t0.contact_place AS contact_place5, 
  t0.contact AS contact6, 
  t0.contact_id AS contact_id7, 
  t0.person_id AS person_id8 
FROM 
  supContact t0 
WHERE 
  t0.person_id = 1490

I'm not sure how to proceed with debugging from here. The desired functionality is to have multiple entries show up of course.

The Code

Controller Snippet

public function showAction($personId = 0, $organizationId = 0)
    {
        $person = $this->getDoctrine()
                        ->getRepository('AEDTracker:Genperson')
                        ->find($personId);

        return $this->render('AEDTracker:Personnel:show.html.twig', array(
            'person' => $person,
            'organizationId' => $organizationId,
        ));
    }

Twig Template Snippet

    {% if person.contacts is empty %}
    <tr><td colspan="100">No entries</td></tr>
    {% else %}
      {% for item in person.contacts %}
        <tr class="contact_edit" module="contact" name="{{ item.contactId }}">
           <td></td>
           <td>{{ item.contactType }}</td>
           <td>{{ item.contactPlace }}</td>
           <td>{{ item.contact }}</td>
           <td><a href="{{ path('personnelEditContact', { 'contactId': item.contactId, 'organizationId': organizationId }) }}">Edit</a></td>
        </tr>
       {% endfor %}
     {% endif %}

Genperson.orm.xml

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  <entity name="AED\Tracker\Entity\Genperson" table="genPerson">
    <id name="personId" type="integer" column="person_id">
      <generator strategy="IDENTITY"/>
    </id>

    <!-- Skipped unimportant fields -->

    <one-to-many field="contacts" target-entity="Supcontact" mapped-by="person" fetch="EAGER" />
  </entity>
</doctrine-mapping>

Supcontact.orm.xml

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  <entity name="AED\Tracker\Entity\Supcontact" table="supContact">
    <id name="contactId" type="integer" column="contact_id">
      <generator strategy="IDENTITY"/>
    </id>
    <field name="personId" type="integer" column="person_id" nullable="true" />

    <!-- Removed unimportant fields -->

    <many-to-one field="person" target-entity="Genperson" inversed-by="contacts">
        <join-column name="person_id" referenced-column-name="person_id" />
        <cascade>
            <cascade-persist />
            <cascade-merge />
        </cascade>
    </many-to-one>
  </entity>
</doctrine-mapping>

Any help would be greatly appreciated.

  • 写回答

1条回答 默认 最新

  • doulan0297 2014-05-22 17:56
    关注

    Like a silly person, I didn't try something obvious for this fix.

    There must be a bug between Symfony 2.3 and 2.4, because updating fixed this issue entirely.

    For those that may ever stumble on this, to update you must download the new composer.json file located here into the root folder of the project, then run

    php composer.phar update
    

    All dependencies will be updated, including the Symfony core and Doctrine library. Make sure you test before pushing this to your production environment.

    However, oddly enough I had to keep the fetch="EAGER" parameter in my ORM XML files to keep the functionality working. This may not be a complete solution and someone else may have some further insight. Ideally I'd like the application to continue using lazy loading.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?