Home » Eclipse Projects » EclipseLink » [JPA] @Index used in cache?(If an @Index is placed on a field will EclipseLink be able to use that field in a search of the cache)
[JPA] @Index used in cache? [message #717193] |
Fri, 19 August 2011 10:52  |
Eclipse User |
|
|
|
I have an class that has two unique identitifers 'mainId' and 'otherId', both of type String, either one can be used to find(QueryMapItem.class, id) a single object. This is not a composite key case, but just a case in which two subsystems demand different approaches. Therefore only one can be annotated with @Id, let us say 'mainId', and I assume therefore that only one, 'mainId', can be the Primary Key (PK). The other can however be annotated as an @Index. If I use a JPA Query to search for objects of this class based on 'otherId' will Eclipselink be able to use the cache before it queries the database? Or does Eclipselink always go to the database for queries which are not on PKs, before it uses the cache? I ask because it seems that a Query on anything other than a PK always results in a call to the DB. (I have not yet tried with unique='true' on the Index.
The example;
@Entity
public class QueryMapItem {
@SuppressWarnings("unused") //used by JPA
@ManyToOne
private QuerySingleton singleton;
@Index(columnNames="otherId")
@Basic
private String otherId;
@Id
private String mainId;
@Version
private int version;
@Basic
private Integer property;
// Bonus empty constructor generated for JPA
protected QueryMapItem() {
super();
}
.....
@Entity@NamedQueries({
@NamedQuery(name = "uk.co.his.experiment8.model.query.QuerySingleton.uniqueMapItem", query = "SELECT o FROM QueryMapItem o WHERE o.otherId = :otherId", hints={@QueryHint(name=QueryHints.CACHE_USAGE, value=CacheUsage.CheckCacheThenDatabase), @QueryHint(name=QueryHints.QUERY_TYPE, value=QueryType.ReadObject)}),
})
public class QuerySingleton {
@Id
protected String id = "1";
@SuppressWarnings("unused")
// used by JPA
@Version
private int version;
public IMapItem getMapItem(Integer otherId, EntityManager em) {
Query q = em
.createNamedQuery("uk.co.his.experiment8.model.query.QuerySingleton.uniqueMapItem");
q.setParameter("otherId", otherId.toString());
try {
java.lang.Object r = q.getSingleResult();
return (QueryMapItem) r;
} catch (javax.persistence.NoResultException ex) {
return null;
}
}
Thanks
[Updated on: Fri, 19 August 2011 13:23] by Moderator
|
|
| | | | | | | | | | | |
Re: (no subject) [message #726004 is a reply to message #720494] |
Fri, 16 September 2011 07:46  |
Eclipse User |
|
|
|
Thanks for your reply.
So just to clarify I am using a NamedQuery;
@Entity
@NamedQueries({
@NamedQuery( name = "uk.co.his.experiment8.model.query.QuerySingleton.uniqueMapItem", query = "SELECT o FROM QueryMapItem o WHERE o.otherId = :otherId",
hints={
@QueryHint(name=QueryHints.CACHE_USAGE, value=CacheUsage.CheckCacheThenDatabase),
@QueryHint(name=QueryHints.QUERY_TYPE, value=QueryType.ReadObject)}),
})
Chris said
Quote:"What you are looking for is in-memory querying, which is documented here:
http://wiki.eclipse.org/Introduction_to_EclipseLink_Queries_(ELUG)#How_to_Use_In-Memory_Queries
You might try
q.setHint("eclipselink.cache-usage", "CheckCacheThenDatabase");
with q.getSingleResult();"
but I assume that a NamedQuery with a
@QueryHint(name=QueryHints.CACHE_USAGE, value=CacheUsage.CheckCacheThenDatabase) hint is no different than using the API as outlined by Chris.
Since otherId is not a Primary Key this Query will not be able to do a cache hit, and will consequently trawl the Cache and will therefore be a an InMemory Query which may well be slower than bypassing the cache and going direct to the DB, especially if I use the @Index annotation to index the table by the otherId column.
With the new @CacheIndex feature of Eclipselink I should be able to achieve a cache-hit on otherId, which should be faster than a query on to the db. Sounds great thanks!
That about sums it up?
You said;
Quote:
"...it should not go to the database if the object with the id is in the cache. Are you seeing otherwise?"
No. It does not.
[Updated on: Fri, 16 September 2011 07:49] by Moderator
|
|
|
(no subject) [message #726006 is a reply to message #720494] |
Fri, 16 September 2011 07:46  |
Eclipse User |
|
|
|
Thanks for your reply.
So just to clarify I am using a NamedQuery;
@Entity
@NamedQueries({
@NamedQuery( name = "uk.co.his.experiment8.model.query.QuerySingleton.uniqueMapItem", query = "SELECT o FROM QueryMapItem o WHERE o.otherId = :otherId",
hints={
@QueryHint(name=QueryHints.CACHE_USAGE, value=CacheUsage.CheckCacheThenDatabase),
@QueryHint(name=QueryHints.QUERY_TYPE, value=QueryType.ReadObject)}),
})
Chris said
"What you are looking for is in-memory querying, which is documented here:
http://wiki.eclipse.org/Introduction_to_EclipseLink_Queries_(ELUG)#How_to_Use_In-Memory_Queries
You might try
q.setHint("eclipselink.cache-usage", "CheckCacheThenDatabase");
with q.getSingleResult();"
but I assume that a NamedQuery with a
@QueryHint(name=QueryHints.CACHE_USAGE, value=CacheUsage.CheckCacheThenDatabase) hint is no different than using the API as outlined by Chris.
Since otherId is not a Primary Key this Query will not be able to do a cache hit, and will consequently trawl the Cache and will therefore be a an InMemory Query which may well be slower than bypassing the cache and going direct to the DB, especially if I use the @Index annotation to index the table by the otherId column.
With the new @CacheIndex feature of Eclipselink I should be able to achieve a cache-hit on otherId, which should be faster than a query on to the db. Sounds great thanks!
That about sums it up?
You said;
"...it should not go to the database if the object with the id is in the cache. Are you seeing otherwise?"
|
|
|
Goto Forum:
Current Time: Tue Jul 08 21:13:05 EDT 2025
Powered by FUDForum. Page generated in 0.05424 seconds
|