Skip to content

Working with associations

ccapndave edited this page Feb 26, 2011 · 9 revisions

This section of the documentation will explain how to work with associations in Flextrine. You should understand how to map associations in Doctrine before reading this chapter.

For the purposes of this chapter, lets create a few entities with some associations between them that we can use as examples.

Doctor.php

<?php
namespace vo;

/**
 * @Entity
 */
class Doctor {

    /** @Id @Column(type="integer") @GeneratedValue(strategy="IDENTITY") */
    public $id;
        
    /** @Column(length=100, type="string") */
    public $name;

    /** @OneToMany(targetEntity="Patient", inversedBy="doctor") */
    public $patients;
    
}

Patient.php

<?php
namespace vo;

/**
 * @Entity
 */
class Patient {

    /** @Id @Column(type="integer") @GeneratedValue(strategy="IDENTITY") */
    public $id;
        
    /** @Column(length=100, type="string") */
    public $name;

    /** @ManyToOne(targetEntity="Doctor", mappedBy="patients") */
    public $doctor;

    /** @ManyToMany(targetEntity="Disease") */
    public $diseases;
    
}

Disease.php

<?php
namespace vo;

/**
 * @Entity
 */
class Disease {

    /** @Id @Column(type="integer") @GeneratedValue(strategy="IDENTITY") */
    public $id;
        
    /** @Column(length=100, type="string") */
    public $name;
    
}

The example entities here define the following relationships:

  • A bi-directional one to many relationship from Doctor to Patient (i.e. a Doctor has many Patients, and many Patients have one Doctor)
  • A uni-directional many to many relationship from Patient to Disease (i.e. many Patients have many Diseases)

Establishing associations

Establishing associations in Flextrine is fairly trivial. Note that in the following examples we will assume that doc is a Doctor and p1 and p2 are Patients, and that these entities are already MANAGED.

// Associate both patients with the doctor
p1.doctor = doc;
p2.doctor = doc;

em.flush();
// Associate both patients with the doctor
doc.patients.addItem(p1);
doc.patients.addItem(p2);

em.flush();

Notice that we can set either side of the bi-directional relationship in order to establish the association. As of v0.9 Flextrine manages both sides of a relationship automatically. This is an important point, as it is different to many other ORMs (Doctrine, Hibernate, etc) which require you to set both sides of the relationship.

Both of the examples above will have exactly the same result - setting p1.doctor = doc will call doc.patients.addItem(p1) automatically behind the scenes, and calling doc.patients.addItem(p1) will call p1.doctor = doc automatically too.

This means that you don't have to worry about the concept of owning and inverse sides when coding in Flex.

Removing associations

Removing associations in Flextrine is just as easy. All the following code examples do exactly the same thing. Once again, Flextrine makes sure that both sides of the bi-directional relationship stay in sync.

// Un-associate both patients from the doctor
p1.doctor = null;
p2.doctor = null;

em.flush();
// Un-associate both patients from the doctor
doc.patients.removeItem(p1);
doc.patients.removeItem(p2);

em.flush();
// Un-associate all patients from the doctor
doc.patients.removeAll()

em.flush();

Using transactional write-behind

It is quite possible (and in fact, recommended) to create and associate entities in a single flush(). The following example creates new Patients and Diseases, establishes associations between them all, and writes everything to the database with a single call.

var p3:Patient = new Patient();
p3.name = "Mr Sickly";
em.persist(p3);

var scrofula:Disease = new Disease();
scrofula.name = "Scrofula";
em.persist(scrofula);

doc.patients.addItem(p3);
p3.diseases.addItem(scrofula);

em.flush();