Query results are not up to date for entities, not primitives

#1

When using the CriteriaBuilder to query, the loaded list are not refreshed according to the latest updates.
But, when using the JPQL Query, the list are refreshed, and, when I querying for primitive fields like Strings, the list of primitives are loading refreshed too.

Any variations on update side does not any diference. The problem is only solved when changing the query mode, from CriteriaBuilder to JPQL or from Entity to Primitive.

What´s now?

#2

This could be the result of getting query results from the cache.

There is no difference between criteria queries and string based JPQL queries regarding the cache (and actually every criteria query it converted by ObjectDB to JPQL). But some cache operations cannot be used with queries that return values rather than entities, so these queries are different.

Could you please post the configuration file that you are using, demonstrate the queries and explain how updates are performed?

Note that updates by queries bypass the cache and may result in not being seen by queries:

"Updating entity objects in the database using an UPDATE query may be slightly more efficient than retrieving entity objects and then updating them, but it should be used cautiously because bypassing the EntityManager may break its synchronization with the database. For example, the EntityManager may not be aware that a cached entity object in its persistence context has been modified by an UPDATE query. Therefore, it is a good practice to use a separate EntityManager for UPDATE queries."

ObjectDB Support
#3

Ok. The question of Bypass does not any diferrence.

I am using some generic functions to build generic TypedQuerys.
I just realized that the data retrieving up to date if I do not use the generic on parameters of JPA functions!

This is the update:

em
     .createQuery(
       "UPDATE PersonData SET"
        + " personCode = :pessoaCode,"
        + " personName = :personName,"
        + " personEmail = :personEmail"
        + " WHERE person.personID == :personID")

 

I really need to use my generic functions to build the typedquerys!

#4

After such an update queries should return up to date results, if:

  • You are using a new EntityManager (i.e. with no old cache), and
  • The 2nd level data cache is disabled or explicitly bypassed by the query.
ObjectDB Support
#5
<!-- ObjectDB Configuration -->

<objectdb>

<general>
  <temp path="$temp/ObjectDB" threshold="64mb" />
  <network inactivity-timeout="0" />
  <url-history size="50" user="true" password="true" />
  <log path="$objectdb/log/" max="8mb" stdout="false" stderr="false" />
  <log-archive path="$objectdb/log/archive/" retain="90" />
  <logger name="*" level="info" />
</general>

<database>
  <size initial="131072kb" resize="131072kb" page="2kb" />
  <recovery enabled="true" sync="false" path="." max="128mb" />
  <recording enabled="false" sync="false" path="." mode="write" />
  <locking version-check="true" />
  <processing cache="1024mb" max-threads="80" />
  <query-cache results="2048mb" programs="1024000" />
  <extensions drop="temp,tmp" />
  <activation code="XXXX-XXXX-XXXX-XXXX-XXXX" />
</database>

<entities>
  <enhancement agent="true" reflection="warning" />
  <cache ref="strong" level2="0mb" />
  <fetch hollow="false" />
  <persist serialization="false" />
  <cascade-persist always="auto" on-persist="false" on-commit="true" />
  <dirty-tracking arrays="false" />
</entities>

<schema>
</schema>

<server>
  <connection port="6136" max="100" />
  <data path="F:\ObjectDB\db-files" />
  <!--
  <replication url="objectdb://localhost/test.odb;user=XXXXX;password=XXXXX" />
  -->
</server>

<users>
  <user username="XXXXX" password="XXXXX">
   <dir path="/" permissions="access,modify,create,delete" />
  </user>
  <user username="$default" password="$$$###">
   <dir path="/$user/" permissions="access,modify,create,delete">
    <quota directories="5" files="20" disk-space="5mb" />
   </dir>
  </user>
  <user username="user1" password="user1" />
</users>

<ssl enabled="false">
  <server-keystore path="$objectdb/ssl/server-kstore" password="pwd" />
  <client-truststore path="$objectdb/ssl/client-tstore" password="pwd" />
</ssl>

</objectdb>
#6

Updates are done perfectly well.
The problem is in the fact that I'm building the typedquerys through use of generic parameters over JPA functions.

#7

Your configuration indicates that the 2nd level data cache is disabled.

Therefore, running the query on a new EntityManager (which does not have old data cached yet) should always return fresh results.

> The problem is in the fact that I'm building the typedquerys through use of generic parameters over JPA functions.

Could you please explain this in more details?

You may have to post a simple test case to demonstrate the issue.

ObjectDB Support
#8

I did these tests using a new EntityManager for both, UPDATE and TypedQuery, and the situation was not be resolved.

#9

I can not detail all the code of generic functions, but a piece of logic is this:

private void root(Class<?> type) {
  Root<?> root = criteriaQuery.from(type);
}

private <X> void select(Object object) {
  ((CriteriaQuery<X>) criteriaQuery).select((Selection<X>) object);
}

For completeness, I'm using only super-interfaces, so I can reuse all generic methods.

#10

In order to be able to explore this issue, you will have to post a simple test case that demonstrates the issue.

ObjectDB Support
#11

Regards.

It is a very deep and conceptual issue.

I really dont know how to write a complete simple test case for you and dont past all my source.

The important alert is this bug, and is it very critical!

 

#12

If you cannot isolate this problem into a simple test case because of code complexity, it is quite likely that the complex code hides a misuse of ObjectDB UPDATE queries, which as mentioned in #2 above have severe natural limitation in respect of getting up to date data from later queries.

Try to replace UPDATE queries completely with standard JPA update.

Unfortunately besides this tip (and based on the information provided so far) there is nothing else that we can do, unless you find a way to demonstrate the problem with a simple isolated test case.

ObjectDB Support
#13

I can not isolate only the Select query. It is the update query:

EntityManagerFactory emf = Persistence
  .createEntityManagerFactory("PersistenceUnit");
EntityManager em2 = emf
  .createEntityManager();
EntityTransaction tr = em2
  .getTransaction();
tr
  .begin();
em2
  .createQuery(
    "UPDATE PersonData SET"
     + " personCode = :personCode,"
     + " personName = :personName,"
     + " personEmail = :personEmail"
     + " WHERE person.personID == :personID")
  .setParameter(
    "personCode",
    personData
      .getPersonCode())
  .setParameter(
    "personName",
    personData
      .getPersonName())
  .setParameter(
    "personEmail",
    personData
      .getPersonEmail())
  .setParameter(
    "personID",
    personID)
  .executeUpdate();
em2
  .flush();
em2
  .clear();
tr
  .commit();
#14

The update query by itself is fine, the problem is with the exact way in which data is retrieved later. Only with a complete runnable test case in this format we will be able to provide further advice.

ObjectDB Support
#15

You could delete this post? I'll create a new one with this issue properly.
Not close. Delete.

#16

We usually do not delete forum threads.

But you may abandon this thread and open a new one if you think it could help.

ObjectDB Support
#17

I have identified that the problem lies elsewhere, not in the generic parameters.
When I can explain this question correctly will open another post.
This post may be closed or deleted.
Very thanks!

#18

I'm just waiting to see what they will do to me in my professional life, to continue the series of posts of bugs.
Currently I am working without pay.
yes heart

Reply