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
> 

Reply via email to