Thanks John. In this particular case, the only object modified is the object 
sent to the callback, so I'm probably safe in this case—but you probably saved 
my some-point-in-the-future ass with that valuable piece of info :).

Any thoughts on modifying the relationship join column without exposing it? Or 
is my only option to expose it and modify it on the entity class?

- hugi


> On 4 Apr 2019, at 12:31, John Huss <johnth...@gmail.com> wrote:
> 
> There can be issues if you modify other objects inside lifecycle callbacks
> (a callback won't be called on that object). I would recommend doing the
> mods in validateForSave instead.
> 
> On Thu, Apr 4, 2019 at 6:44 AM Hugi Thordarson <h...@karlmenn.is> wrote:
> 
>> 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
>>>> 
>>> 
>> 
>> 

Reply via email to