We'd like to use another L2 cache for our big JPA application. We are trying to achieve a shared cache between multiple servers.
We use Eclipselink as JPA implementation, and some legacy codes uses internal Eclipselink API's, so switching is not an option.
Coherence/Toplink Grid seems too expensive (4000$/cpu?).
Is there a way we could plug another cache implementation? Is something specified in JPA 2 (I can't find anything in the specs, but maybe I just misread it)? Proprietary (=Eclipselink specific) solutions are ok, as long as they are somewhat documented or simple enough (we don't want that to break).
Is there a way we could plug another cache implementation?
Did you investigate the use of the EclipseLink shared object cache that comes with EclipseLink? Going by the description, the shared object cache is not confined to a single EntityManager alone, and is available across the lifecycles of several Entity managers, i.e. across several transactions. It is of course, constrained to the lifecycle of an EntityManagerFactory, which may be as live as long as the application is running in the container.
The EclipseLink shared object cache is different from Oracle Coherence, and I believe it is not licensed and packaged separately, thereby making it available on all containers.
JPA does not specify a pluggable cache interface. I don't know if it ever will, but if it does, my bet is that it won't be until after the resurrected JSR-107 finishes defining a standard API to object caches, which JPA would then be able to use. It might also have to wait for JSR 347, which is defining another cache interface, whose relationship to JCache is somewhat unclear (there is open factional warfare between and within the groups, with some members of the 107 expert group trying to declare 347 an independent republic, and invade Mexico).
So, until then, you're at the mercy of your provider's cache interface. I am not an EclipseLink expert, but last time i looked, i couldn't see a pluggable second-level cache interface. In fact, i think only Hibernate and, of course, DataNucleus, have them.
Most cache implementations are not distributed (other than Coherence), just local.
EclipseLink already supports a share cache and cache coordination for caching in a cluster.
What cache do you intent to use, and what benefit do you intend to get from it?
EclipseLink does support integration with 3rd party caches, this API was created for the Coherence integration, although Coherence is the only cache that currently provides an integration.
Related
I have used the cache2k in my java project and it was so simple (key-value pair) and easy to use. Now I want to know is if cache2k is a persistent or non-persistent cache.
I found the answer in here
https://stackoverflow.com/a/23709996/12605243 which was said at 2014 stated that it was gonna be updated to persistent cache.
So my question is 'Am I using a persistent or non persistent cache?'. I have read their docs but unable to find it.
Basically its possible to add persitence via CacheLoader and CacheWriter. We use that in several ways to use file system or database as storage. When adding persistence this way the cache operates in the so called "cache through" mode. Some operations of the cache, especially get and put operate transparently and read or write the data via the loader and writer to the storage. Other operations, like CAS operations, just interact with the in-memory cache.
The persistence feature as it was planed was meant to be transparent for all cache operations. Although its feasible and the basic work is done in the internal infrastructure, we don't have a big need for it. Other features and tasks seem more important. However, I am happy to hear about potential use cases.
Infinispan has eviction policy, lifespan for specific to entity. From below question we can make the change in persistence.xml.
Infinispan - set per Entity expiration.lifespan
My question is there a way to do this in annotation in that particular entity?
I am not aware of any such config. The reason for the absence of it is probably because Infinispan (and other cache providers) are general-purpose caching frameworks which in general are not aware of Hibernate second-level caching specifics.
On the other hand, again in general, Hibernate and java.persistence do not interfere with specific cache provider implementations and APIs. That means that a cache provider may even not allow defining expiration policy while still being perfectly able to serve as Hibernate L2 cache.
However, you could define your own annotations and set the Infinispan config values programmatically. You could turn it to an interesting open source project, if there are none so far that do similar thing. :)
I have 2 projects:
Java EE - with Rest API
Pure Java using Java Scheduler that calls project 1.
In both I would like to use Hibernate.
Since the are using the same database, I would like to share the same Hibernate session
What is the way to do it?
EDITED
I want to use the same Hibernate cache! Not only the classes
Extract the entities, and potentially some common data access classes, in a jar, and use this jar in both applications.
You can use Hibernate Level 2 Cache (likne Ehcache). The L2 cache is responsible for caching records across multiple sessions but only for primary key lookups. If you want queries cache you can't do that with Hibernate when multipel sessions are being used.
You can make your own separate cache implementation (also using EhCache) and have some centralized way of signaling to it when it is dirtied by writes from a certain application.
I am currently working on a project that uses JPA (Toplink, currently) for its persistence. Currently, we are running a single application server, but, for redundancy, we would like to add a load balancer and another application sever (and possibly more as it grows).
First, I'm running into the issue of JPA caching. Since two processes will be updating the same database, the JPA cache returns the cached value rather than going to the database. I see how to turn that off, and the database itself implements a level of caching. Is turning off the cache completely the way to go here? I see the ways to tell JPA to always get from the database at a query level, but in a multi-server environment, it seems that you'll always want that to happen.
Along with this specific question, I'm interested in anyone out there who has implemented a JPA solution with multiple application servers and what problems arose during the implementation (and any suggestions you have).
Thanks much.
As you have found, you can disable the shared cache, see http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching or http://wiki.eclipse.org/EclipseLink/FAQ/How_to_disable_the_shared_cache%3F
There are also other options available in EclipseLink depending on your data and requirements.
A list of option include:
Disable shared cache
Enable cache coordination (see, http://www.eclipse.org/eclipselink/api/2.1/org/eclipse/persistence/config/PersistenceUnitProperties.html#COORDINATION_PROTOCOL)
Set a cache invalidation timeout (see, http://www.eclipse.org/eclipselink/api/2.1/org/eclipse/persistence/annotations/Cache.html#expiry%28%29)
Enable optimistic locking, this will ensure that any stale object cannot be updated, when an update on stale data occurs it will fail, and EclipseLink will automatically invalidate the object in the cache.
Investigate the Oracle TopLink integration of EclipseLink and Oracle Coherence to provide a distributed cache.
See also, http://en.wikibooks.org/wiki/Java_Persistence/Caching#Caching_in_a_Cluster
There is no perfect solution, the solution used normally depend on the data/class, normally an application has a set of read-only classes, read-mostly classes and write mostly classes. Personally I would enable the cache for the read-only with a 1 day timeout, enable the cache with cache coordination for the read-mostly, and disable the cache for the write mostly.
We are looking at implementing a caching framework for our application to help improve the overall performance of our site.
We are running on Websphere 6.1, Spring, Hibernate and Oracle. The focus currently is on the static data or data that changes very little through out the day but is used a lot.
So any info would be great. I have started my google search and reading but wanted to get a feel for what has worked for members of the community. One of the things that we are interested in is the ability to have the system invalidate the cache when a change does happen in the underlining data.
Thanks
Update:
I came across an article on the IBM web site where it says that Hibernate's Cluster aware caches in conjunction with WebSphere Application Server has not been determined yet; therefore, is is not yet determined whether or not their use is supported.
Thoughts on that? We are running in a clustered environment.
Well the hibernate cache system does just that, I used ehCache effectively and easily with Hibernate (and the second level cache system).
Lucene could be an option too depending on the situation. Hibernate Search or Compass could help with that (although it might take some major work).
Replication using Terracotta could also be an option although I've never done it.
Hibernate has first and second level caching built in. You can configure it to use EhCache, OSCache, SwarmCache, or C3P0 - your choice.
You can also leverage WebSphere's default cache i.e. DynaCache to implement the second level cache. This will allow you to administer, monitor and configure your cache leveraging WebSphere caching infrastructure
I've used ehCache and OSCache and found OSCache to be easier to configure and use.
One of the things that we are
interested in is the ability to have
the system invalidate the cache when a
change does happen in the underlining
data.
From what I can see, Hibernate doesn't actually do the above - from Hibernate's docs:
Be careful. Caches are never aware of
changes made to the persistent store
by another application (though they
may be configured to regularly expire
cached data).
Obviously what it means is that a cache doesn't have ESP, and can't tell if an app not in the cluster has called straight DML on the database - but I am guessing that what you want is an ability to expose a service for legacy apps to hook in and invalidate the cache when they do update that data. And there isn't, to my knowledge, a suggestion about how this might be done.