My guess would be “no”. I suggest you don’t model the relationships until the foreign systems are fixed or removed. In the meanwhile, I would implement methods as the relationships, that would know if there’s a fictitious value or not and return NULL for the relationship. When the other systems are fixed, remove the method and implement the relationship normally.
> On Apr 4, 2019, at 6:39 AM, Hugi Thordarson <h...@karlmenn.is> wrote: > > I spoke a little too soon—my solution isn't sufficient, who'd have thunk it > :). > > Some of the columns with "fictional null values" are used in relationships. > For example, I can have an invoice with customer_id "-1" to indicate that > there's no related customer. > > As I'm done cleaning up the DB, these will eventually end up as actual > foreign keys with nulls instead of that -1, so I'd like to model the > relationship, hide the FK in the ObjEntity and use the "customer" > relationship (I've actually modeled it like that already and it works fine > for read operations, but of course everything explodes once I try to write > and object with a null customer to the DB and "customer_id" is set to null). > > So, I kind of need to be doing this on the DbEntity level (if customer is > null, write "-1" to the customer_id). > > Is this at all possible? > > Cheers, > - hugi > > >> On 4 Apr 2019, at 10:09, Hugi Thordarson <h...@karlmenn.is> wrote: >> >> 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 >