getBeans() always returns the cached value even if asked not to

I have a logic_hook, well a series of logic hooks really, that creates two RLIs, then updates those RLIs and then in another hook it tests those RLI to see if they are completed.

The update is to set them to completed.  I looked in the DB and they are set to completed.

That last step (in another logic file) has this code

            $oppBean->load_relationship('revenuelineitems');
            $rliBeans = $oppBean->revenuelineitems->getBeans(array('use_cache' => false),array('use_cache' => false));

Which returns the two RLIs but BOTH of them are shown as NOT being completed.  I looked at the getBeans() function and there is no mention of the 'use_cache' param.  If its in the cache it just returns it.

Also I dont know why the update to completed is not reflected in the cache but I see that a lot.  I use the 'use_cache' param just about everywhere in system-wide code (stuff that users dont generally run in the UI). 

My current work around is to do this

$oppBean->load_relationship('revenuelineitems');
			$oppBean->revenuelineitems->beans=array();
            $rliBeans = $oppBean->revenuelineitems->getBeans(array('use_cache' => false));

So I empty the cache before I getBeans().

Does anyone have some wisdom for me?

  • There is no evidence that class Link2 evaluates parameter 'use_cache' anyhow.

    Also, after browsing Link2 class I realized that you may need to fix one of your lines:

    Replace

    $oppBean->revenuelineitems->beans=array();

    by

    $oppBean->revenuelineitems->beans=null; // or empty or anything but array();

    Method getBeans evaluates if beans has bean loaded before by checking if it is an array, that is it, it doesn't not evaluate if the array is not empty because a relationship may return an empty list.

    Good luck!

    André Lopes
    Lampada Global
    Skype: andre.lampada
  • I'll look into that replacement but as far as I know I am trying to get past line 465

    if (empty($this->beans[$id]))


    so if $this->beans is an empty array I am OK.  Are you seeing something else?   I am working in 10.0.4 at the moment.




  • I can not see anything wrong neither in your code or related methods at Link2 and BeanFactory. That is weird!

    André Lopes
    Lampada Global
    Skype: andre.lampada
  • If you look at the

    Link2->getBeans()

    code, you'll see it starts with:

        	if (!is_array($params))
                $params = array();
    
            if (!$this->loaded && empty($params)) {
                $this->load();
            }
    

    The "$this->load()" actually sets the 'beans' property to null:

        public function load($params = array())
        {
            // free previously allocated memory to avoid the issue when <old-dataset> + <new-dataset> = memory limit reached
            $this->rows = null;
    
            $this->rows = $this->query($params)['rows'];
            $this->beans = null;
            $this->loaded = true;
        }
    

    So, somewhat ironically, the reason it is using the already-set beans array rather than fetching it again is because you are passing it that 

    array('use_cache' => false)

    as the first argument. As already mentioned, there is nothing about the Link2 getBeans class that indicates that it accepts the params as you intended for them to be understood. Looking through the rest of the code base, and based on the above code where it calls "load", I think what you are wanting to do is:

    $oppBean->load_relationship('revenuelineitems');
    $oppBean->revenuelineitems->resetLoaded();
    $rliBeans = $oppBean->revenuelineitems->getBeans();

    The resetLoaded will set the "loaded" property to false, which will then make it so that (if the params argument is empty) it calls load(), which will in turn re-run the query and empty the beans property.

    Note that getBeans looks like:

        public function getBeans($params = array(), $retrieveParams = array())
    

    The "params" argument are params passed to "$this->query()", while the retrieveParams argument are passed along to this line:

    $tmpBean = BeanFactory::retrieveBean($rel_module, $id, $retrieveParams);

    Since BeanFactory::retrieveBean also has its own cache, this may (I haven't tested) also result in getting back the existing object, which may not reflect your changes (I think they should, since objects are always passed by reference, but caching is tricky, as we all know). So with that in mind, to avoid both the Link2 beans array "cache" and the BeanFactory cache, you would probably want to do:

    $oppBean->load_relationship('revenuelineitems');
    $oppBean->revenuelineitems->resetLoaded();
    $rliBeans = $oppBean->revenuelineitems->getBeans([],["use_cache"=>false]);

    This will ensure that the relationship data is reloaded and that the retrieved bean is not from cache either.

  • I will try this and get back to you, thanks a lot for the complete description.

  • Thanks for sharing complete description. It is very helpful for the Developers.

    Bruce McIntyre