tags:

views:

114

answers:

3

We're using jpa with Toplink as an implementation and came up with a problem about refreshing lists of entities.

Basically this is the scenario:

private List<Entity> findAll()
{
    final String sql = "SELECT e from " + anEntityClass.getSimpleName() + " e";
    final Query query = itsManager.createQuery(sql);
    List<Entity> result = query.getResultList();

    return result;
}

But if we modify the database by external means, a second call to findAll() method will return outdated information because it reuses the info stored in cache.

One solution to this problem is to specify

query.setHint("toplink.refresh", "True");

So we always get refreshed data. But then we are depending on Toplink and we would face a problem if we need to change providers.

I know that there's an entityManager.refesh() method but I've only seen it in combination with entitytManager.find() to get only one entity.

Is there any standard way to get fresh data for a list of entities?

A: 

I guess you can retain that property, and change it to the new one IF you change the persistence provider. I presume that this will be your least problem if such a change ever happens.

You can also set such a property per persistent unit.

And you can use EntityManager.clear(), if the scope of this scenario is limited (so that you don't end up clearing the session at every query)

Bozho
A: 

This is such a frustrating part of working with JPA, I think and something that I've struggled with in a number of applications. The practice that we've established is to actually just clear the session entirely and re-run the query that got us our resultset to begin with. One of the issues of refresh() is cascades. If you have lazily loaded collections or other references that have been fetched into memory, each of those items will get refreshed as well which can make the entire process take a long time.

But I have to say that the pragmatic side of me says that you're so unlikely to change your persistence provider that if you have something that works with TopLink, then just go forward with it. Learn how to make the best use of the tools you have and don't worry about the "someday maybe" chance that you'll need to switch to Hibernate or something else.

BryanD
+1  A: 

You can set a property in persistence.xml to disable caching for either all Entitys or specific Entitys.

<persistence-unit name="local" transaction-type="RESOURCE_LOCAL">
    <provider>oracle.toplink.essentials.PersistenceProvider</provider>
    <properties>
        <property name="toplink.cache.type.default" value="NONE" />
        <property name="toplink.cache.type.the.class.package.ClassName" value="NONE" />
    </properties>
</persistence-unit>

See http://www.oracle.com/technology/products/ias/toplink/JPA/essentials/toplink-jpa-extensions.html#TopLinkCaching for more information.

Dan Godfrey