Hi all,
I'm currently working on a legacy system. The DB has a lot of columns where 
null should actually be allowed, but instead those fields are non-nullable and 
get other values (empty string, "0", "-1" etc) written to them to indicate the 
absence of a value. Yay.

Unfortunately I can't just do the right thing; make the fields nullable and 
start writing nulls, since that would make other (non Cayenne) parts of the 
system explode, so I have to create a temporary workaround while I work through 
each column and make it nullable and fix (or kill) the legacy apps.

What I'd like to do is write my application logic as if the column was 
nullable, setting nulls when I want to, but when the object goes to the DB, 
"legacy nulls" are written to the DB instead (empty string or "-1" or whatever).

I have a working solution, I just wanted to check if you guys would have a 
better or more performant solution or see anything potentially wrong with what 
I'm doing.

What I'm doing is creating an interface (HasFictionalNullValues) which can be 
implemented by entity classes that require it. It defines a single method that 
can be implemented like…

public class SomeEntityClass extends _SomeEntityClass implements 
HasFictionalNullValues {

        @Override
        Map<Property,Object> fictionalNullValues) {
                Map<Property,Object map = new HashMap<>();
                map.put( NAME, "" );
                map.put( AGE, -1 );
                return map;
        }

        [...rest of class body...]
}

…then I add a listener to my DataDomain to catch new and updated objects

public class FictionalNullValuesListener {

        @PrePersist( { BaseDataObject.class } )
        @PreUpdate( { BaseDataObject.class } )
        public void onPrePersist( BaseDataObject object ) {
                if( object instanceof HasFictionalNullValues ) {
                        
((HasFictionalNullValues)object).fictionalNullValues().forEach( ( property, 
replacementNullValue ) -> {
                                if( property.getFrom( object ) == null ) {
                                        property.setIn( object, 
replacementNullValue );
                                }
                        } );
                }
        }
}

Any comments on this practice or something I'm missing?

Cheers,
- hugi

Reply via email to