You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by Lon Varscsak <lo...@gmail.com> on 2023/04/26 22:09:34 UTC

Force update of column

Hey all,

I of course have an unusual situation that I'm not sure how to handle.  :)

I was going to write a lot of background, but I don't know if it would help
or just confuse the situation. 🤣

The situation I have is in one specific situation, I'd like Cayenne to
always add an attribute to the UPDATE/INSERT statements, not just if the
value is changed.  Can you think of any way to achieve that?

Thanks,

Lon

Re: Force update of column

Posted by Nikita Timofeev <nt...@objectstyle.com>.
Hi Lon,

That's a really tricky question. Cayenne seems to stand firm on not
updating something that didn't change.
The shortest path as I see it is to trick Cayenne into believing such
fields are changed.

Here's a small prototype that does the trick.
It uses reflection to get some private parts of the context,
probably you could customize the Cayenne stack a bit
in order to make this more user-friendly.


public class ForceUpdateUtil {
   private final Method methodGetChanges;
   private final Field fieldSnapshot;

   public ForceUpdateUtil() {
      try {
         methodGetChanges =
ObjectStore.class.getDeclaredMethod("getChangesByObjectId");
         fieldSnapshot = ObjectDiff.class.getDeclaredField("snapshot");
      } catch (NoSuchMethodException | NoSuchFieldException ex) {
         throw new RuntimeException(ex);
      }
      methodGetChanges.setAccessible(true);
      fieldSnapshot.setAccessible(true);
   }

   public void forceUpdate(Persistent persistent, String attribute) {
      DataContext objectContext = (DataContext)persistent.getObjectContext();
      try {
         @SuppressWarnings("unchecked")
         Map<Object, ObjectDiff> changesById = (Map<Object,
ObjectDiff>) methodGetChanges.invoke(objectContext.getObjectStore());
         ObjectDiff objectDiff = changesById.get(persistent.getObjectId());
         @SuppressWarnings("unchecked")
         Map<String, Object> snapshot = (Map<String, Object>)
fieldSnapshot.get(objectDiff);

         // here's an actual action we want
         // we tell the cached snapshot that the field have null value
instead of the real one
         // so that flush action will think there's a change and it
needed to be committed
         snapshot.put(attribute, null);

      } catch (InvocationTargetException | IllegalAccessException ex) {
         throw new RuntimeException(ex);
      }
   }
}

And here is the usage example.
Note that you need to have some changes for the object:

@Test
public void test() {
   ForceUpdateUtil util = new ForceUpdateUtil();

   Artist artist = SelectById.query(Artist.class, 1).selectOne(context);
   assertNotNull(artist);

   artist.setDateOfBirth(new Date());
   util.forceUpdate(artist, Artist.ARTIST_NAME.getName());

   context.commitChanges();
}


On Wed, May 3, 2023 at 12:58 AM Lon Varscsak <lo...@gmail.com> wrote:
>
> Haha, yeah, it's a bit of an odd situation...could you point me to the
> right bit in your source where I could tinker?
>
> On Fri, Apr 28, 2023 at 4:59 AM Andrus Adamchik <aa...@gmail.com> wrote:
>
> > Hi Lon,
> >
> > certainly not via "standard" means. That logic is not configurable. But
> > everything is customizable of course :)
> >
> > Thanks,
> > Andrus
> >
> > > On Apr 27, 2023, at 12:09 AM, Lon Varscsak <lo...@gmail.com>
> > wrote:
> > >
> > > Hey all,
> > >
> > > I of course have an unusual situation that I'm not sure how to handle.
> > :)
> > >
> > > I was going to write a lot of background, but I don't know if it would
> > help
> > > or just confuse the situation. 🤣
> > >
> > > The situation I have is in one specific situation, I'd like Cayenne to
> > > always add an attribute to the UPDATE/INSERT statements, not just if the
> > > value is changed.  Can you think of any way to achieve that?
> > >
> > > Thanks,
> > >
> > > Lon
> >
> >



--
Best regards,
Nikita Timofeev

Re: Force update of column

Posted by Lon Varscsak <lo...@gmail.com>.
Haha, yeah, it's a bit of an odd situation...could you point me to the
right bit in your source where I could tinker?

On Fri, Apr 28, 2023 at 4:59 AM Andrus Adamchik <aa...@gmail.com> wrote:

> Hi Lon,
>
> certainly not via "standard" means. That logic is not configurable. But
> everything is customizable of course :)
>
> Thanks,
> Andrus
>
> > On Apr 27, 2023, at 12:09 AM, Lon Varscsak <lo...@gmail.com>
> wrote:
> >
> > Hey all,
> >
> > I of course have an unusual situation that I'm not sure how to handle.
> :)
> >
> > I was going to write a lot of background, but I don't know if it would
> help
> > or just confuse the situation. 🤣
> >
> > The situation I have is in one specific situation, I'd like Cayenne to
> > always add an attribute to the UPDATE/INSERT statements, not just if the
> > value is changed.  Can you think of any way to achieve that?
> >
> > Thanks,
> >
> > Lon
>
>

Re: Force update of column

Posted by Andrus Adamchik <aa...@gmail.com>.
Hi Lon,

certainly not via "standard" means. That logic is not configurable. But everything is customizable of course :) 

Thanks,
Andrus

> On Apr 27, 2023, at 12:09 AM, Lon Varscsak <lo...@gmail.com> wrote:
> 
> Hey all,
> 
> I of course have an unusual situation that I'm not sure how to handle.  :)
> 
> I was going to write a lot of background, but I don't know if it would help
> or just confuse the situation. 🤣
> 
> The situation I have is in one specific situation, I'd like Cayenne to
> always add an attribute to the UPDATE/INSERT statements, not just if the
> value is changed.  Can you think of any way to achieve that?
> 
> Thanks,
> 
> Lon