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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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 <[email protected]> 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