Temporal based Entity Columns

Hi,

I’m working on a project that the database structure may change regularly for but for historical reasons the old structure remains. It is related to government requirements and they like to change things regularly to keep themselves employed.

For example say I have an Entity Passport that currently has a column IssuingAuthority and in a few months they decide they no longer want that but now want IssuingCountry and IssuingOffice.

So I go ahead and add in the new columns but leave the old one. When viewing the screens for historic data I need to see the old column and its data and not the new ones and for new data in the screens I see the new columns and not the old one.

So it is sort of a temporal requirement around columns.

What I was thinking is maybe I can add an attribute to the Columns similar to @Composition and @OnDelete. My attribute might be say @ValidityPeriod and accepts a from and to date. I could then use this in screen code I’m guessing to deal with the UI.

My question is if I add an attribute to an entity like this is it accessible in the rest of the system and where would it be on the Entity or in the Metadata somewhere?

Hi John,

The simplest way to get an annotation of an entity field is via the AnnotatedElement corresponding to the field, which is available in metadata. Say if you have Foo.bar entity attribute annotated, you can get the annotation like this:

MetaProperty property = metadata.getClassNN(Foo.class).getPropertyNN("bar");
ValidityPeriod validityPeriod = property.getAnnotatedElement().getAnnotation(ValidityPeriod.class);

A more extensible way is to employ the meta-annotations mechanism which is used for many standard annotations in the platform.

First, create your annotation class and annotate it with @MetaAnnotation, then the framework will pull your annotation attributes to metadata:

package com.company.sample;

import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@MetaAnnotation
public @interface ValidityPeriod {

    String value() default "";
}

Then you can get the annotation value in any part of the system using the below code:

MetaProperty property = metadata.getClassNN(Foo.class).getPropertyNN("bar");

String value = (String) metadata.getTools()
        .getMetaAnnotationAttributes(property.getAnnotations(), ValidityPeriod.class)
        .get("value");

Instead of value, you can have any annotation attributes - they will be available via the Map returned by the getMetaAnnotationAttributes() method.

This mechanism allows you to annotate entities using metadata.xml, i.e. without modifying the source code of the entity class. It is the only way if the entity belongs to an application component.

2 Likes

@knstvk Thanks for the answer that is perfect.