Doctrine Gotchas – delete cascade, SoftDelete and foreignType

These are mistakes anyone can make, as proved by our team of experienced developers who only came across these late into a project – after developing with Doctrine for over 6 months.

Cascading / Transitive persistence

In Doctrine there are two ways to define a cascade, one will tell Doctrine what to do, the other defines how that condition is set up on your database when Doctrine builds the sql commands. The reason this was a gotcha for me, is that we only ever used one of the types, and were completely unaware of the other one! The Doctrine manual is quite long, and unless you’ve read it several times cover to cover it’s easy to miss these things – although next time I will at least be reading the appropriate section of the manual, regardless of what I think I already know.

So, you want a delete cascade? You might do something like this in your yaml file:

      type: integer
      class:       User
      local:       user_id
      foreign:     id
      onDelete:    CASCADE

What the above definition says is that this phone number is connected to a user, and if the user record is deleted – in order to maintain database integrity with foreign keys, the corresponding phone number records should also be deleted. This is perfect behaviour – but Doctrine does not do anything with it, it simply sets up the database to handle it, so if you are using a dbms that supports delete cascades then everything will be handled at the database level.

Adding softDelete to the equation

So here comes the gotcha, all of our tables use the softDelete behaviour – which means that instead of the row being deleted, a flag is set (deleted=true) which then magically makes the row appear deleted in all your queries (Providing you have dql callbacks turned on). This means that the row is never actually deleted at the databse level, and thus the cascade is never applied. Now I always knew this, I mean I wouldn’t install a behaviour before knowing what it does right? What I wrongly assumed was that the call to onDelete: CASCADE would take care of “soft deleting” my relations too, but it doesn’t, in fact that line is effectively useless when combined with softDelete. For that you need to set the doctrine cascade parameter:

  actAs: [softDelete]
      type: integer
      class:       User
      local:       user_id
      foreign:     id
      foreignType: one
      cascade:     [delete]

Now the behaviour will be as expected. If you are using softDelete and your application has a lot of delete operations, you should take some time to understand what is happening, because Doctrine must fetch and load all of the related objects and then check their relations and cascade settings and so on, so in a large system deleting a single user could result in quite a lot of database queries and cpu time. It is for this reason that database level cascades are preferable, so maybe being more picky about which models you apply the softDelete behaviour would be prudent. Learn more about Doctrine Transitive Persistance.

Defining types of foreign key relations

This one is also one of those “read the manual” situations, but similarly to the above example what caught us out here is that we again thought that there was only one option for defining what we wanted to do, when in fact there were too parameters we should have been considering. This gotcha also only applies if you are defining your relations in a yaml file, as the problem lies in its interpretation when Doctrine builds the base classes.

Look at the following example:

      type: integer
      notnull: true
      class:       Payment
      local:       id
      foreign:     user_id
      foreignType: many

The intention was that a user could have multiple payments, and it seemed to make sense to define it using the foreignType parameter above, however when the model was built – this always resulted in a $this->hasOne(…) statement being created, because what was actually happening is that we were not defining the relationship at the other end, we were actually defining it at the local end! So foreignType: many actually means “Many users can have one payment” – hence the interpretation of $this->hasOne(..)

In actual fact using the foreignType key is mostly useless, as Doctrine “guesses” this side of the relationship. It’s only necessary if Doctrine guesses incorrectly and you need to override it, our example above should actually have been using the “type” parameter, which defines the relationship from the other perspective:

      type: integer
      notnull: true
      class:    Payment
      local:    id
      foreign:  user_id
      type:     many

Adding [ foreignType: one ] to this schema declaration would have no offect, as Doctrine would guess it to be the case (in this example). The above declaration will now correctly form a $this->hasMany(…) statement in your base class. To make it easy to remember, just forget about foreignType all together unless you come across a special case where you nee it – and prepend the word “has” to the type parameter, that should give you a clue as to what you are defining.

So, with one-to-one relationships, the type parameter is unnecessary, with one-to-many you specify the type: many (Doctrine will guess the one part) and with many-to-one you also do not need to specify the type as it will be guessed based on how you’ve got the relation set up from the other model’s perspective.

Read more about relations in the Doctrine manual.


it’s hard to believe that after 6 months of coding a large application that currently has over 30,000 lines of code and growing we could have a schema file with several useless calls to onDelete: CASCADE and even more useless calls to foreignType. It’s even harder to believe that in the early days of the project, we simply overrode the setup methods to add the relations that we needed, when the Schema.yml file failed to come up with the goods. Next time I think I’ll spend a little more time with the documentation, although we are of course experts now – so maybe next time we won’t need to? ūüėČ

PHP TestFest Norway 2009

Test Fest Norway 2009

If you use PHP and have ever wondered why you get something so cool for free, maybe a little tang of guilt can creep in. Contributing to the language in one way or another is a great way to pay something back, and there are many ways to do so, one of which is to write tests….

Tests keep the code sane. Every time things change, the tests can be run to make sure that everything still works ok – just like the php tests you (hopefully) write in your own projects. The best way to maintain this stability for the language itself is also to have as much code covered by tests as possible.

Every year, the PHP team organises TestFest, aiming to introduce testing to the masses in the most straightforward way. All you have to do is find out where your nearest event is being held and sign up. You will be given everything you need and assisted in every way to help you write at least one test – hopefully many more.

Details of TestFest 2009 Norway have just been released, if you are in the area, check it out!

Aker – from farm to fame


The word Aker comes up a lot in and around Oslo, and after a brief discussion about it yesterday, it struck me that using familiar names can help us to learn less familiar vocabulary.

The word comes from old Norse for “acre” and was the name of an old farm, which helped to name a church (the old Aker church) which then went on to name the district and spawn the other things we know and love today. You can read more about that on the Wikipedia page.

Words to learn that “Aker” can help us to remember

  • Hus = House – You should be familiar with Akershus (county), literally “the House of Aker” but don’t read too much into that without reading the following reference also:
  • Festning = Fortress – Akershus Festning is the fortress overlooking the Oslo Fjord. It’s name fully expanded means something like “The fortified house of Aker”. The district of Akershus was named after the fortress, not the other way around!
  • Elv = River (feminine so “the river” is “elva”) – Akerselva is the river that runs through Oslo, literally “the river of Aker”
  • √ėstre = Eastern – one of the main roads running in an Easterly direction out of Oslo parallel to the E6 is √ėstre Aker Vei, literally “Eastern Aker road”. We may already know that “√ėst” means “East” so this helps us to remember the method to convert to “Eastern”.
  • Brygge = Jetty – You need to be in the marine industry to know exactly how this would translate in English (wharf, quay, mooring, dock, etc), but jetty is probably closest. Situated in the Oslo habour is the trendy district of Aker Brygge where you will find shops, restaurants, apartments and more. (You should also be aware that Brygge can be a verb – to brew).
  • Sykehus = Hospital – “Aker Sykehus” and “Akershus sykehus” (Known as A-hus) are 2 of the hospitals serving Akershus.
  • Gamle Kirke = Old church – Gamle Aker kirke is one of the reasons for the name, and is the oldest existing building in Oslo.
  • Bakke = Hill – Akersbakken is the hill that Gamle Aker Kirke resides on, and also the name of the adjacent road


Hopefully reading some interesting facts and making some connections in your brain between vocabulary and real world situations will help to improve your (and my) Norwegian. I have certainly learned a few things from producing this blog post, and I hope you do from reading it ūüôā

Norwegian phrase of the day – 20/04/09 (Oversv√łmmelse)


It has been a while since the last one, sorry about that! I have been orienteering in England and dealing with a bout of conjunctivitis but I’m back in the office now and raring to go. Today’s phrase got a bit messy because I’m still a bit tired and out of practice – so forgive me, but also be thankful there are a few points to discuss ūüôā

Today’s word: Oversv√łmmelse

  • Translation: Flood
  • Pronunciation: aw-ver-shvur-merl-ser

First attempt

Det har vært så lenge
siden jeg har skrivet
noen ting, derfor trenger jeg
en oversv√łmmelse av inspirasjon!
Siden jeg er ikke helt sikker om
setningen opp der, skal jeg også
sier at oversv√łmmelse i fjor
i England var kjempedårlig og
mange folk måtte dro fra husene deres.
Det var bra vær for ender!


  • There is not really a Norwegian equivalent for “it has been so long since” so we should stick with “it is so long since”, det er s√• lenge siden
  • √• skrive, skrev, har skrevet
  • derfor does not really work here, we can replace it with at jeg trenger
  • Ikke placement can be tricky, in this sentence (a subordinate clause) ikke must precede the finite verb: Siden jeg ikke er helt sikker
  • Om and P√• can also be tricky for English speakers – here we should use sikker p√•
  • The next sentence is a bit messy, and is better written as forige setning, or sentingen over
  • “Skal jeg ogs√• sier at” is better written as vil jeg ogs√• si at. Vil and Skal can also cause some difficulties, since skal generally means “will, shall” and vil generally means “would like to, want to”. Sier should also have been in the infinitive, √• si.
  • kjemped√•rlig does not really work in this context, so we can introduce a new word: forferdelig (terrible)
  • dro should be dra, as in English you would say “had to leave” not “had to left”.
  • Since we are talking about their own houses, we should say husene sine, otherwise we could be referring to “their” as in anybodies houses.

Final edit:

Det er så lenge
siden jeg har skrevet
noen ting at jeg trenger
en oversv√łmmelse av inspirasjon!
Siden jeg ikke er helt sikker på
forrige setning, vil jeg også
si at oversv√łmmelse i fjor
i England var forferdelig, og
mange folk måtte dra fra husene sine.
Det var bra vær for ender!


It has been so long since
I have written anything that
I need a flood of inspiration!
Since I'm not totally sure about
the previous sentence, I will also
say that the floods last year
in England were terrible and many
people had to leave their houses.
It was nice weather for ducks!

Russ is short for Russell… or is it?

Even before I came to Norway, I knew that I would have problems with my name because in recent years I’ve decided to use the shortened version (Russ) rather than it’s true form (Russell). Every time people ask my name, it takes a few tries to convince them that yes, I am named after the end of year student celebrations that take place every year in Norway!

In fact, I applied for a job for the Norwegian “Russ service” web service ( which would have been pretty cool, as then I would have been

Anyway, the reason I started writing this was because of the Russ is not short for Russell blog post which I’ve just read, do take a look and think of how it is for me and my name during this time of celebration and chaos.

« Previous PageNext Page »