openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Adrian Gonzalez <adr_gonza...@yahoo.fr>
Subject Re: Portable way to use query cache
Date Wed, 23 Jan 2013 14:37:13 GMT
Ok, just implemented second approach (build on top of first one) - tested it with Hibernate
4.x.

You'll just have to set query hint "javax.persistence.cache.retrieveMode" to USE :
public List<Civilite> findAllCivilite() {
return entityManager
.createNamedQuery(NamedQueries.CIVILITE_FIND_ALL,
Civilite.class)
.setHint("javax.persistence.cache.retrieveMode", CacheRetrieveMode.USE)
.getResultList();
}

And use an em produced / decorated like that :
public class EntityManagerConfigProducer {

@PersistenceContext
private EntityManager entityManager;

@Produces
public EntityManager getEntityManager() {
return new PortableEntityManager(entityManager);
}
}

Regards,

Adrian

P.S. Here's the code I've used for this :

=== PortableEntityManager.java (don't like the name :( )

public class PortableEntityManager extends DelegatingEntityManager {
private static final String RETRIEVE_MODE = "javax.persistence.cache.retrieveMode";
private static final String STORE_MODE = "javax.persistence.cache.storeMode";

public PortableEntityManager(EntityManager em) {
super(em);
}

@Override
public Query createQuery(String qlString) {
return new CacheSupportQuery(getDelegate().createQuery(qlString));
}

@Override
public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) {
return new CacheSupportTypedQuery<T>(getDelegate().createQuery(criteriaQuery));
}

@Override
public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass)
{
return new CacheSupportTypedQuery<T>(getDelegate().createQuery(qlString, resultClass));
}

@Override
public Query createNamedQuery(String name) {
return new CacheSupportQuery(getDelegate().createNamedQuery(name));
}

@Override
public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass)
{
return new CacheSupportTypedQuery<T>(getDelegate().createNamedQuery(name, resultClass));
}

@Override
public Query createNativeQuery(String sqlString) {
return new CacheSupportQuery(getDelegate().createNativeQuery(sqlString));
}

@Override
public Query createNativeQuery(String sqlString, @SuppressWarnings("rawtypes") Class resultClass)
{
return new CacheSupportQuery(getDelegate().createNativeQuery(sqlString,
resultClass));
}

@Override
public Query createNativeQuery(String sqlString, String resultSetMapping) {
return new CacheSupportQuery(getDelegate().createNativeQuery(sqlString,
resultSetMapping));
}

public static class CacheSupportTypedQuery<X> extends DelegatingTypedQuery<X>
{

public CacheSupportTypedQuery(TypedQuery<X> query) {
super(query);
}

@Override
public TypedQuery<X> setHint(String hintName, Object value) {
return portableQueryHint(hintName, value, this);
}
}

public static class CacheSupportQuery extends DelegatingQuery {

public CacheSupportQuery(Query query) {
super(query);
}

@Override
public Query setHint(String hintName, Object value) {
return portableQueryHint(hintName, value, this);
}
}
private static <Q extends DelegatingQuery> Q portableQueryHint(String hintName, Object
value, Q query) {
Object retrievalMode = null;
Object storeMode = null;
boolean cacheHint = false;
if (RETRIEVE_MODE.equals(hintName)) {
retrievalMode = value;
storeMode = (query.getHints() != null ? query.getHints().get(STORE_MODE) : null);
cacheHint = true;
} else if (STORE_MODE.equals(hintName)) {
retrievalMode = (query.getHints() != null ? query.getHints().get(RETRIEVE_MODE) : null);
storeMode = value;
cacheHint = true;
}
if (cacheHint) {
if ((storeMode != null && !storeMode
.equals(CacheStoreMode.BYPASS))
|| (retrievalMode != null && !retrievalMode
.equals(CacheStoreMode.BYPASS))) {
JpaUtils.cacheQuery(query.getDelegate(), true);
} else {
JpaUtils.cacheQuery(query.getDelegate(), false);
}
}
query.getDelegate().setHint(hintName, value);
return query;
}
}


=== DelegatingEntityManager.java

public class DelegatingEntityManager implements EntityManager {

private EntityManager em;
public DelegatingEntityManager(EntityManager em) {
this.em = em;
}

@Override
public void persist(Object entity) {
em.persist(entity);
}

@Override
public <T> T merge(T entity) {
return em.merge(entity);
}

@Override
public void remove(Object entity) {
em.remove(entity);
}

@Override
public <T> T find(Class<T> entityClass, Object primaryKey) {
return em.find(entityClass, primaryKey);
}

@Override
public <T> T find(Class<T> entityClass, Object primaryKey,
Map<String, Object> properties) {
return em.find(entityClass, primaryKey, properties);
}

@Override
public <T> T find(Class<T> entityClass, Object primaryKey,
LockModeType lockMode) {
return em.find(entityClass, primaryKey, lockMode);
}

@Override
public <T> T find(Class<T> entityClass, Object primaryKey,
LockModeType lockMode, Map<String, Object> properties) {
return em.find(entityClass, primaryKey, lockMode, properties);
}

@Override
public <T> T getReference(Class<T> entityClass, Object primaryKey) {
return em.getReference(entityClass, primaryKey);
}

@Override
public void flush() {
em.flush();
}

@Override
public void setFlushMode(FlushModeType flushMode) {
em.setFlushMode(flushMode);
}

@Override
public FlushModeType getFlushMode() {
return em.getFlushMode();
}

@Override
public void lock(Object entity, LockModeType lockMode) {
em.lock(entity, lockMode);
}

@Override
public void lock(Object entity, LockModeType lockMode,
Map<String, Object> properties) {
em.lock(entity, lockMode, properties);
}

@Override
public void refresh(Object entity) {
em.refresh(entity);
}

@Override
public void refresh(Object entity, Map<String, Object> properties) {
em.refresh(entity, properties);
}

@Override
public void refresh(Object entity, LockModeType lockMode) {
em.refresh(entity, lockMode);
}

@Override
public void refresh(Object entity, LockModeType lockMode,
Map<String, Object> properties) {
em.refresh(entity, lockMode, properties);
}

@Override
public void clear() {
em.clear();
}

@Override
public void detach(Object entity) {
em.detach(entity);
}

@Override
public boolean contains(Object entity) {
return em.contains(entity);
}

@Override
public LockModeType getLockMode(Object entity) {
return em.getLockMode(entity);
}

@Override
public void setProperty(String propertyName, Object value) {
em.setProperty(propertyName, value);
}

@Override
public Map<String, Object> getProperties() {
return em.getProperties();
}

@Override
public Query createQuery(String qlString) {
return em.createQuery(qlString);
}

@Override
public <T> TypedQuery<T> createQuery(CriteriaQuery<T> criteriaQuery) {
return em.createQuery(criteriaQuery);
}

@Override
public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass)
{
return em.createQuery(qlString, resultClass);
}

@Override
public Query createNamedQuery(String name) {
return em.createNamedQuery(name);
}

@Override
public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass)
{
return em.createNamedQuery(name, resultClass);
}

@Override
public Query createNativeQuery(String sqlString) {
return em.createNativeQuery(sqlString);
}

@Override
public Query createNativeQuery(String sqlString, @SuppressWarnings("rawtypes") Class resultClass)
{
return em.createNativeQuery(sqlString, resultClass);
}

@Override
public Query createNativeQuery(String sqlString, String resultSetMapping) {
return em.createNativeQuery(sqlString, resultSetMapping);
}

@Override
public void joinTransaction() {
em.joinTransaction();
}

@Override
public <T> T unwrap(Class<T> cls) {
return em.unwrap(cls);
}

@Override
public EntityManager getDelegate() {
return em;
}

@Override
public void close() {
em.close();
}

@Override
public boolean isOpen() {
return em.isOpen();
}

@Override
public EntityTransaction getTransaction() {
return em.getTransaction();
}

@Override
public EntityManagerFactory getEntityManagerFactory() {
return em.getEntityManagerFactory();
}

@Override
public CriteriaBuilder getCriteriaBuilder() {
return em.getCriteriaBuilder();
}

@Override
public Metamodel getMetamodel() {
return em.getMetamodel();
}
}


=== DelegatingQuery.java

public class DelegatingQuery implements Query {
private Query delegate;
public DelegatingQuery(Query delegate) {
this.delegate = delegate;
}
public Query getDelegate() {
return delegate;
}

@SuppressWarnings("rawtypes")
public List getResultList() {
return delegate.getResultList();
}

public Object getSingleResult() {
return delegate.getSingleResult();
}

public int executeUpdate() {
return delegate.executeUpdate();
}

public Query setMaxResults(int maxResult) {
return delegate.setMaxResults(maxResult);
}

public int getMaxResults() {
return delegate.getMaxResults();
}

public Query setFirstResult(int startPosition) {
return delegate.setFirstResult(startPosition);
}

public int getFirstResult() {
return delegate.getFirstResult();
}

public Query setHint(String hintName, Object value) {
return delegate.setHint(hintName, value);
}

public Map<String, Object> getHints() {
return delegate.getHints();
}

public <T> Query setParameter(Parameter<T> param, T value) {
return delegate.setParameter(param, value);
}

public Query setParameter(Parameter<Calendar> param, Calendar value,
TemporalType temporalType) {
return delegate.setParameter(param, value, temporalType);
}

public Query setParameter(Parameter<Date> param, Date value,
TemporalType temporalType) {
return delegate.setParameter(param, value, temporalType);
}

public Query setParameter(String name, Object value) {
return delegate.setParameter(name, value);
}

public Query setParameter(String name, Calendar value,
TemporalType temporalType) {
return delegate.setParameter(name, value, temporalType);
}

public Query setParameter(String name, Date value, TemporalType temporalType) {
return delegate.setParameter(name, value, temporalType);
}

public Query setParameter(int position, Object value) {
return delegate.setParameter(position, value);
}

public Query setParameter(int position, Calendar value,
TemporalType temporalType) {
return delegate.setParameter(position, value, temporalType);
}

public Query setParameter(int position, Date value,
TemporalType temporalType) {
return delegate.setParameter(position, value, temporalType);
}

public Set<Parameter<?>> getParameters() {
return delegate.getParameters();
}

public Parameter<?> getParameter(String name) {
return delegate.getParameter(name);
}

public <T> Parameter<T> getParameter(String name, Class<T> type) {
return delegate.getParameter(name, type);
}

public Parameter<?> getParameter(int position) {
return delegate.getParameter(position);
}

public <T> Parameter<T> getParameter(int position, Class<T> type) {
return delegate.getParameter(position, type);
}

public boolean isBound(Parameter<?> param) {
return delegate.isBound(param);
}

public <T> T getParameterValue(Parameter<T> param) {
return delegate.getParameterValue(param);
}

public Object getParameterValue(String name) {
return delegate.getParameterValue(name);
}

public Object getParameterValue(int position) {
return delegate.getParameterValue(position);
}

public Query setFlushMode(FlushModeType flushMode) {
return delegate.setFlushMode(flushMode);
}

public FlushModeType getFlushMode() {
return delegate.getFlushMode();
}

public Query setLockMode(LockModeType lockMode) {
return delegate.setLockMode(lockMode);
}

public LockModeType getLockMode() {
return delegate.getLockMode();
}

public <T> T unwrap(Class<T> cls) {
return delegate.unwrap(cls);
}
}


=== DelegatingTypedQuery.java

public class DelegatingTypedQuery<X> extends DelegatingQuery implements TypedQuery<X>
{

public DelegatingTypedQuery(TypedQuery<X> delegate) {
super(delegate);
}
@SuppressWarnings("unchecked")
public TypedQuery<X> getDelegate() {
return (TypedQuery<X>) super.getDelegate();
}

@Override
public List<X> getResultList() {
return getDelegate().getResultList();
}

@Override
public X getSingleResult() {
return getDelegate().getSingleResult();
}

@Override
public TypedQuery<X> setMaxResults(int maxResult) {
return getDelegate().setMaxResults(maxResult);
}

@Override
public int executeUpdate() {
return getDelegate().executeUpdate();
}

@Override
public TypedQuery<X> setFirstResult(int startPosition) {
return getDelegate().setFirstResult(startPosition);
}

@Override
public TypedQuery<X> setHint(String hintName, Object value) {
return getDelegate().setHint(hintName, value);
}

@Override
public int getMaxResults() {
return getDelegate().getMaxResults();
}

@Override
public <T> TypedQuery<X> setParameter(Parameter<T> param, T value) {
return getDelegate().setParameter(param, value);
}

@Override
public int getFirstResult() {
return getDelegate().getFirstResult();
}

@Override
public TypedQuery<X> setParameter(Parameter<Calendar> param,
Calendar value, TemporalType temporalType) {
return getDelegate().setParameter(param, value, temporalType);
}

@Override
public TypedQuery<X> setParameter(Parameter<Date> param, Date value,
TemporalType temporalType) {
return getDelegate().setParameter(param, value, temporalType);
}

@Override
public Map<String, Object> getHints() {
return getDelegate().getHints();
}

@Override
public TypedQuery<X> setParameter(String name, Object value) {
return getDelegate().setParameter(name, value);
}

@Override
public TypedQuery<X> setParameter(String name, Calendar value,
TemporalType temporalType) {
return getDelegate().setParameter(name, value, temporalType);
}

@Override
public TypedQuery<X> setParameter(String name, Date value,
TemporalType temporalType) {
return getDelegate().setParameter(name, value, temporalType);
}

@Override
public TypedQuery<X> setParameter(int position, Object value) {
return getDelegate().setParameter(position, value);
}

@Override
public TypedQuery<X> setParameter(int position, Calendar value,
TemporalType temporalType) {
return getDelegate().setParameter(position, value, temporalType);
}

@Override
public TypedQuery<X> setParameter(int position, Date value,
TemporalType temporalType) {
return getDelegate().setParameter(position, value, temporalType);
}

@Override
public TypedQuery<X> setFlushMode(FlushModeType flushMode) {
return getDelegate().setFlushMode(flushMode);
}

@Override
public TypedQuery<X> setLockMode(LockModeType lockMode) {
return getDelegate().setLockMode(lockMode);
}

@Override
public Set<Parameter<?>> getParameters() {
return getDelegate().getParameters();
}

@Override
public Parameter<?> getParameter(String name) {
return getDelegate().getParameter(name);
}

@Override
public <T> Parameter<T> getParameter(String name, Class<T> type) {
return getDelegate().getParameter(name, type);
}

@Override
public Parameter<?> getParameter(int position) {
return getDelegate().getParameter(position);
}

@Override
public <T> Parameter<T> getParameter(int position, Class<T> type) {
return getDelegate().getParameter(position, type);
}

@Override
public boolean isBound(Parameter<?> param) {
return getDelegate().isBound(param);
}

@Override
public <T> T getParameterValue(Parameter<T> param) {
return getDelegate().getParameterValue(param);
}

@Override
public Object getParameterValue(String name) {
return getDelegate().getParameterValue(name);
}

@Override
public Object getParameterValue(int position) {
return getDelegate().getParameterValue(position);
}

@Override
public FlushModeType getFlushMode() {
return getDelegate().getFlushMode();
}

@Override
public LockModeType getLockMode() {
return getDelegate().getLockMode();
}

@Override
public <T> T unwrap(Class<T> cls) {
return getDelegate().unwrap(cls);
}
}

----- Mail original -----
De : Adrian Gonzalez <adr_gonzalez@yahoo.fr>
À : "users@openjpa.apache.org" <users@openjpa.apache.org>
Cc : 
Envoyé le : Mercredi 23 janvier 2013 14h21
Objet : Re: Portable way to use query cache



1. After looking a little bit, I don't think we can use hint for query caching in OpenJPA.
If this is confirmed, I'll open a JIRA for this.


2. Meanwhile, I've created this little utility [1] to do enable portable query caching.

I've tested it only with Hibernate for the moment, but it should work with OpenJPA and toplink.

To use it, just do :

JpaUtils.cacheQuery(entityManager.createNamedQuery("myNamedQuery", Civilite.class)).getResultList();


3. Perhaps there's a better approach - using a decorating entityManager, which decorates the
query and intercepts setHint calls and call the appropriate API whenever the hint is "query.cache"
(or sthing like that) :
Then you'll just have to do :
entityManager.createNamedQuery("myNamedQuery", Civilite.class).setHint("query.cache").getResultList(); 


With a CDI producer - or equivalent doing :

@PersistenceContext
private EntityManager em;

@Produces
public EntityManager getEntityManager () {
  return new EntityManagerDecorator(em);
}

WDYT ?

[1] JpaUtils code :
public final class JpaUtils {
public static <X extends Query> X cacheQuery(X query) {
return cacheQuery(query, true);
}
public static <X extends Query> X cacheQuery(X query, boolean cache) {
String queryClassname = query.getClass().getName(); 
if (queryClassname.startsWith("org.hibernate")) {
query.setHint("org.hibernate.cacheable", cache);
} else if (queryClassname.startsWith("org.apache.openjpa")) {
OpenJPAEntityManager oem = ((OpenJPAQuery<?>) query).getEntityManager();
OpenJPAEntityManagerFactory oemf = oem.getEntityManagerFactory();
QueryResultCache qcache = oemf.getQueryResultCache();
if (cache == true) {
qcache.pin(query);
} else {
qcache.unpin(query);
}
} else if (queryClassname.startsWith("org.eclipse.persistence")) {
query.setHint("eclipselink.query-results-cache", true);
}
return query;
}
}

----- Mail original -----
De : Adrian Gonzalez <adr_gonzalez@yahoo.fr>
À : "users@openjpa.apache.org" <users@openjpa.apache.org>
Cc : 
Envoyé le : Mercredi 23 janvier 2013 10h38
Objet : Portable way to use query cache

Hello,

I'm a newbie with openJPA, I would like to know what's the best way to do query caching (in
a JPA 2.x portable way).
My webapp will run on JBoss 7.x (Hibernate) and Websphere 8 (OpenJPA).


From , [1] there's some proprietary API involved.

Is there a portable way, i.e. using hints instead [2]?

Thanks !

[1] http://openjpa.apache.org/builds/2.0.1/apache-openjpa-2.0.1/docs/manual/main.html
OpenJPAEntityManagerFactory oemf = OpenJPAPersistence.cast(emf);
QueryResultCache qcache = oemf.getQueryResultCache();

[2] entityManager.createNamedQuery(
NamedQueries.ETAT_CONTRAT_FIND_ALL, EtatContrat.class).setHint("openjpa.querycache", true);

Mime
View raw message