Custom OR Mapping

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:

image

In Class1 we are going to make SomePK the primary key.

On Class1 we set PrimaryKey and PrimaryKeyMapper:

image

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

image

 

Doing this mean that we ourselves take responsibility that the key is set and that we do not allow for 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. And 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 primary key – that is both strange and not what Rich wanted – and this is also not supported – hence the error Rich got.

To handle this we need to 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:

image

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

image

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

image

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).

So having this in place I can generate schema and get the following result:

image

Class1 has the SomePK has key – but the Class2 that 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 entry was posted in ORMapping. Bookmark the permalink.

2 Responses to Custom OR Mapping

  1. I have followed this recommendation and using the DefaultORMappingBuilder to specify defaultSingleLinkColumnName to be ID. DB management worked well from the PMP side of things (i.e. create schema, evolve schema, save or mapping to db.
    When I go to the Prototype it seems it does not see the usage of DefaultORMappingBuilder and when trying to evolve database from there it is trying to apply changes that are not aware of the DefaultORMappingBuilder existence.

    Do we miss a setting somewhere?

    Thanks for your help in advance.

  2. Admin says:

    The built in prototyper use a persistence mapper with certain settings that is standard configured. It will not have access to your DefaultORMappingBuilder.
    You will need to compile run wecpof or EcoDebugger in runtime instead.

Leave a Reply

Your email address will not be published. Required fields are marked *

*