You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@cayenne.apache.org by kw...@tybera.com, kw...@tybera.com on 2018/07/31 23:35:10 UTC

SelectById vs SQLSelect cache behavior

I have a situation where multiple applications can make changes to the database, and I need to be able pull data from the database and not use cached data. 

We were running with cayenne 3.1M3 but I found documentation that indicated that SelectById may be better suited to do what I wanted than Cayenne.objectForPK which we were using - but I needed to update.  So I downloaded version 4.0.RC1 and changed this:
	Employee  existingUserInfo = Cayenne.objectForPK(context, Employee.class, userInfo.getId());
to this:
	ObjectContext context = cayenneRuntime.getContext();
	Employee  existingUserInfo = SelectById.query(Employee.class, userInfo.getId()).localCache().selectOne(context);

This appears to have solved my problem.  However, I found that where I was calling SQLTemplate to get the Employee, that I am not getting the latest information because of the cache.  I switched these to use SQLSelect rather than SQLTemplate hoping that SQLSelect would act like SelectById, but it is not.

Here is what I put in to try to test this:
			String sql = "SELECT * from Employee "
					+ " WHERE login_Id = #bind($loginId) " 
					+ " and historical_Date is null ";

			ObjectContext context = cayenneRuntime.getContext();
			Employee emp = SQLSelect.query(Employee.class, sql).params("loginId", userName).localCache().selectOne(context);
			if (emp == null) return null;
			System.out.println("emp middleName=" + emp.getMiddleName());
			Employee emp2 = SelectById.query(Employee.class, emp.getObjectId()).localCache().selectOne(context);
			System.out.println("emp2 middleName=" + emp.getMiddleName());

I access the Employee in my application, and then I change the middle name of the employee in the database.  The first call uses SQLSelect to get Employee emp based on their loginId.   Then I use SelectById to get the same Employee in emp2 based on the objectId for emp.  The calls follow the same pattern of specifying localCache and selectOne with the same context.  However SQLSelect is not picking up the changed middle name, while SelectById does.

What is the best approach to handling this?  I see that SQLSelect is a replacement for SQLTemplate with the new fluid approach, but I am hoping that I can switch to ObjectSelect and it will behave as SelectById.  I also wonder if I should be using ObjectContext context = runtime.newContext(); rather than runtime.getContext();

I am planning on updating to the new 4.1.M2 release.  I don't know if this gives me more/better options.




 

RE: SelectById vs SQLSelect cache behavior

Posted by Kerry Ward <kw...@tybera.com>.
Eliminating .localCache seems to have done the trick.  But why does SelectById pick up changes made directly to the database, rather than picking from the localCache?  At least that seems to be the behavior I was seeing.

-----Original Message-----
From: John Huss <jo...@gmail.com> 
Sent: Wednesday, August 1, 2018 12:14 PM
To: user@cayenne.apache.org
Subject: Re: SelectById vs SQLSelect cache behavior

If you want fresh data you shouldn't use .localCache() or you should pass a cache strategy to refresh the cache.

You can also force objects to be refreshed on the next access or query by using ObjectContext.invalidateObjects.

On Tue, Jul 31, 2018 at 6:35 PM kward@tybera.com <kw...@tybera.com> wrote:

> I have a situation where multiple applications can make changes to the 
> database, and I need to be able pull data from the database and not 
> use cached data.
>
> We were running with cayenne 3.1M3 but I found documentation that 
> indicated that SelectById may be better suited to do what I wanted 
> than Cayenne.objectForPK which we were using - but I needed to update.  
> So I downloaded version 4.0.RC1 and changed this:
>         Employee  existingUserInfo = Cayenne.objectForPK(context, 
> Employee.class, userInfo.getId()); to this:
>         ObjectContext context = cayenneRuntime.getContext();
>         Employee  existingUserInfo = SelectById.query(Employee.class, 
> userInfo.getId()).localCache().selectOne(context);
>
> This appears to have solved my problem.  However, I found that where I 
> was calling SQLTemplate to get the Employee, that I am not getting the 
> latest information because of the cache.  I switched these to use 
> SQLSelect rather than SQLTemplate hoping that SQLSelect would act like 
> SelectById, but it is not.
>
> Here is what I put in to try to test this:
>                         String sql = "SELECT * from Employee "
>                                         + " WHERE login_Id =
> #bind($loginId) "
>                                         + " and historical_Date is 
> null ";
>
>                         ObjectContext context = 
> cayenneRuntime.getContext();
>                         Employee emp = SQLSelect.query(Employee.class, 
> sql).params("loginId", userName).localCache().selectOne(context);
>                         if (emp == null) return null;
>                         System.out.println("emp middleName=" + 
> emp.getMiddleName());
>                         Employee emp2 = 
> SelectById.query(Employee.class, emp.getObjectId()).localCache().selectOne(context);
>                         System.out.println("emp2 middleName=" + 
> emp.getMiddleName());
>
> I access the Employee in my application, and then I change the middle 
> name of the employee in the database.  The first call uses SQLSelect to get
> Employee emp based on their loginId.   Then I use SelectById to get the
> same Employee in emp2 based on the objectId for emp.  The calls follow 
> the same pattern of specifying localCache and selectOne with the same context.
> However SQLSelect is not picking up the changed middle name, while 
> SelectById does.
>
> What is the best approach to handling this?  I see that SQLSelect is a 
> replacement for SQLTemplate with the new fluid approach, but I am 
> hoping that I can switch to ObjectSelect and it will behave as 
> SelectById.  I also wonder if I should be using ObjectContext context 
> = runtime.newContext(); rather than runtime.getContext();
>
> I am planning on updating to the new 4.1.M2 release.  I don't know if 
> this gives me more/better options.
>
>
>
>
>
>



---------------------------------------------
Scanned by SpamSmack http://www.spamsmack.com

Re: SelectById vs SQLSelect cache behavior

Posted by John Huss <jo...@gmail.com>.
If you want fresh data you shouldn't use .localCache() or you should pass a
cache strategy to refresh the cache.

You can also force objects to be refreshed on the next access or query by
using ObjectContext.invalidateObjects.

On Tue, Jul 31, 2018 at 6:35 PM kward@tybera.com <kw...@tybera.com> wrote:

> I have a situation where multiple applications can make changes to the
> database, and I need to be able pull data from the database and not use
> cached data.
>
> We were running with cayenne 3.1M3 but I found documentation that
> indicated that SelectById may be better suited to do what I wanted than
> Cayenne.objectForPK which we were using - but I needed to update.  So I
> downloaded version 4.0.RC1 and changed this:
>         Employee  existingUserInfo = Cayenne.objectForPK(context,
> Employee.class, userInfo.getId());
> to this:
>         ObjectContext context = cayenneRuntime.getContext();
>         Employee  existingUserInfo = SelectById.query(Employee.class,
> userInfo.getId()).localCache().selectOne(context);
>
> This appears to have solved my problem.  However, I found that where I was
> calling SQLTemplate to get the Employee, that I am not getting the latest
> information because of the cache.  I switched these to use SQLSelect rather
> than SQLTemplate hoping that SQLSelect would act like SelectById, but it is
> not.
>
> Here is what I put in to try to test this:
>                         String sql = "SELECT * from Employee "
>                                         + " WHERE login_Id =
> #bind($loginId) "
>                                         + " and historical_Date is null ";
>
>                         ObjectContext context =
> cayenneRuntime.getContext();
>                         Employee emp = SQLSelect.query(Employee.class,
> sql).params("loginId", userName).localCache().selectOne(context);
>                         if (emp == null) return null;
>                         System.out.println("emp middleName=" +
> emp.getMiddleName());
>                         Employee emp2 = SelectById.query(Employee.class,
> emp.getObjectId()).localCache().selectOne(context);
>                         System.out.println("emp2 middleName=" +
> emp.getMiddleName());
>
> I access the Employee in my application, and then I change the middle name
> of the employee in the database.  The first call uses SQLSelect to get
> Employee emp based on their loginId.   Then I use SelectById to get the
> same Employee in emp2 based on the objectId for emp.  The calls follow the
> same pattern of specifying localCache and selectOne with the same context.
> However SQLSelect is not picking up the changed middle name, while
> SelectById does.
>
> What is the best approach to handling this?  I see that SQLSelect is a
> replacement for SQLTemplate with the new fluid approach, but I am hoping
> that I can switch to ObjectSelect and it will behave as SelectById.  I also
> wonder if I should be using ObjectContext context = runtime.newContext();
> rather than runtime.getContext();
>
> I am planning on updating to the new 4.1.M2 release.  I don't know if this
> gives me more/better options.
>
>
>
>
>
>