Yes, this would have been a good idea :). Unfortunately the model (containing dozens of tables and hundreds of relationships) is already completely modeled using relationships and makes heavy use of them (for expressions, ordering, prefetching etc. etc.)
The Cayenne-project was originally created as the reporting-part of the system, so I didn't really hit these issues until now, when we're moving the actual "write" part of the system there as well. Dang… Cheers, - hugi > On 4 Apr 2019, at 11:10, Ken Anderson <k...@anderhome.com> wrote: > > 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 >> >