TheAppFoundry
TheAppFoundry

Reputation: 111

EclipseLink Result Cache not caching results

I want to cache the results of database queries by the query string + the query arguments.

I'm using EclipseLink's result caching to try and achieve this but am hitting the database for every query.

Note: I made an example with the same annotations and logic, but removed all business domain terms.

I have turned on mysql general query log and confirmed the queries are hitting the database everytime. When I change the named query to just be a query by with 1 parameter being the primary key, the query is cached.

I've tried using both @Cache and @Cacheable annotations on the entity, as well as no Cache annotations.

The documentation states, using result caching you don't need the primary key or indexed fields.

@Entity
@Table(name = "Ball")
@XmlRootElement
@Cache
@NamedQueries({
    @NamedQuery(name="Ball.findBallWithColor",
                query="SELECT b FROM Ball b WHERE b.color = :color",
                hints = { 
                        @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE, value = "true"),
                        @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_SIZE, value = "10")
                        }
    )})
public class Blue implements Serializable {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    private BigInteger ballID
    private Color color;

}
public enum Color {

   BLUE,
   YELLOW,
   ORANGE,
   RED;

}

The code that creates the named query and executes it: This query gets called several times through the course of 1 request to our endpoint and the query hits the database everytime.

public List<Ball> findBallsWithColor(Color color) {

        TypedQuery<InstitutionLtvCreditScoreGroup> query = em.createNamedQuery("Ball.findBallWithColor", Ball.class);
        query.setParameter("color", Color.BLUE);
        List<Ball> blueBalls = query.getResultList();

        return blueBalls;

    }

Persistance Unit:

    <persistence-unit name="Example" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>${some_source}</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
        <properties>
            <property name="eclipselink.weaving.changetracking"
                value="false" />
            <property name="eclipselink.target-database" value="MySQL" />


            <property name="eclipselink.cache.coordination.protocol"
                value="fish.payara.persistence.eclipselink.cache.coordination.HazelcastPublishingTransportManager" />
            <property name="eclipselink.cache.coordination.channel"
                value="myChannel" />


            <property name="eclipselink.logging.logger"
                value="org.eclipse.persistence.logging.DefaultSessionLog" />
            <property name="eclipselink.logging.level" value="WARNING" />


            <property name="eclipselink.jdbc.batch-writing" value="JDBC" />

            <property name="eclipselink.jdbc.batch-writing.size"
                value="1000" />
        </properties>
    </persistence-unit>

Upvotes: 4

Views: 1231

Answers (1)

TheAppFoundry
TheAppFoundry

Reputation: 111

After much testing and reading up on specs, and I actually found something very very subtle with why the caching was not working. JPA 2.2 defines the @Cacheable annotation that can be used in conjunction with <shared-cache-mode/> property in the persistence.xml file. We have it defined as follows: <shared-cache-mode>ENABLE_SELECTIVE<shared-cache-mode/>. This means caching is enabled on the entities that are explicitly annotated that they are cached.

Problem is, with the property defined as so in the persistence.xml, we have to use the @cacheable annotation on the entities. EclipseLink 2.7 has annotation extensions, (annotations not found in the spec). One of these is @Cache which is very similar

So with <shared-cache-mode>ENABLE_SELECTIVE<shared-cache-mode/>

@Cache
@Entity
class MyEntity {}

Will not be cached.

@Cacheable(true)
@Entity
class MyEntity{}

Will be cached.

The eclipseLink spec says to use @Cache in place of JPA's @Cacheable, but I presume this would then mean we can't use that persistence property.

Upvotes: 2

Related Questions