Custom OR Mapping

Declaring a Composite key for a reversed database

In this video: https://youtu.be/BmmoAFjaQtc the process of defining a composite primary key is explained.

Here are the steps involved:

  1. On the class (filmactor) find the two foreign keys that together makes the row unique in the database (film_id,actor_id)
  2. Set the both these keys as comma separated on the class (A) (filmactor) primarykey: film_id,actor_id
  3. In the singlelink ends (film (B) and actor (C)) set the columnName (D) to film_id and actor_id respectively
Training Custom OR Mapping 1708350261846.png

Setting the primary key to an existing attribute

We had this issue from Rich W in the forum  – he tried to do a custom OR mapping.

He wanted to pick a modeled attribute to be the primary key in the database.

This is how to accomplish this:

Custom OR Mapping 01.png

In Class1, we make SomePK the primary key.

On Class1, we set PrimaryKey and PrimaryKeyMapper:

Custom OR Mappin 02.png

We also set the SaveAction on the attribute SomePK to Freeze – possible other values DBAssigned and None.

Custom OR Mappin 03.png

Doing this means that we take responsibility for setting the key and we do not allow it to be changed once saved – as is normal for primary keys.

If we had DBAssigned – it will not be set on save – and it will be re-read from the DB once saved. This is for scenarios where you have AutoInc fields in the database.

Rich did all this correctly but could not get it to work – he got errors while trying to generate the database. At first, I could not put my finger on why but then it dawned on me that we have an issue with the DefaultSuperClass.

The package may have a named DefaultSuperClass that all the other classes in the package inherit from. This still has the default primary key mapping.

If you do not have a designed DefaultSuperClass, the auto-generated class EcoModelRoot will assume its place in the standard OR mapping.

So the EcoModelRoot has a standard key named EcoId and the subclass Class1 has the SomePK attribute as the primary key – this is both strange and not what Rich wanted – and this is also unsupported – hence the error Rich got.

To handle this, we instruct the OR mapper to do something about it. In this particular case, the best thing is to skip the EcoModelRoot table. We do this by adding a DefaultORMappingBuilder to the PersistenceMapper:

Custom OR Mappin 04.png

We connect it to both NewMappingProvider and RunTimeMappingProvider of the PersistenceMapper (New is used in design time when doing the create and evolve and runtime is when the app executes):

Custom OR Mapping 05.png

So far, we have changed nothing – this is what would have happened anyway – but we have exposed the defaultORMappingBuilder so that we can tweak it:

Custom OR Mapping 06.png

The most important tweak is ChildMapRootClass – this means that EcoModelRoot, or if you have another modeled DefaultSuperClass, will not get a table of its own – it will be mapped into the child classes. The other tweaks are just for show – I do this because I personally think it looks better with primary keys that follow the pattern above (original value is <Name> and EcoKey).

Having this in place, I can generate a schema and get the following result:

Custom OR Mapping 07.png

Class1 has the SomePK as the key – but Class2, which we did not give any special primary key, has the default <TableName>ID – namely Class2ID. Also, note the single link back to Class1 in the Class2 table – it is named Class1ID.

This page was edited 87 days ago on 08/26/2024. What links here