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 >>>> >>> >> >>