Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Caching or Something else(Entity Efficiency)
Caching or Something else [message #1860920] Fri, 08 September 2023 19:09 Go to next message
Joseph McCay is currently offline Joseph McCayFriend
Messages: 1
Registered: September 2023
Junior Member
I have two Entities. One references a table that is primarily for looking up values and descriptions. This table structure is a legacy table structure, so I can't change the structure. I am using Eclipselink 2.6. Technically it is org.eclipse.persistence:org.eclipse.persistence.jpa:2.6.4 with Payara 5.201 as the server.

The basics for the Entity class for the lookup table is listed below. I have edited it for brevity. I don't think the caching is working.
@Entity
@Table(name = "fapermittypes")
@Cache(  //not sure if this works
  type=CacheType.SOFT, // Cache everything until the JVM decides memory is low.
  size=10000,  // Use 10,000 as the initial cache size.
  expiry=300000,  // 5 minutes
  isolation=CacheIsolationType.SHARED,
  coordinationType=CacheCoordinationType.INVALIDATE_CHANGED_OBJECTS  // if cache coordination is used, only send invalidation messages.
)
@NamedQueries({
    @NamedQuery(name = "PermitType.findAll", query = "SELECT n FROM PermitType n"),
    @NamedQuery(name = "PermitType.findByName", query = "SELECT n FROM PermitType n WHERE n.permittype = :permittypeName")
})
public class PermitType implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(name="permittype")
    private String permitType;

    @Column(name="permittypedesc")
    private String permitTypeDescription;

	...
}


The Entity that contains the many to one reference is listed below. Again, I have edited it for brevity.

@Entity
@Table(name = "myTable")
@NamedQueries({
    @NamedQuery(name = "Permit.findAll", query = "SELECT n FROM Permit n"),
    @NamedQuery(name = "Permit.findBytheName", query = "SELECT n FROM Permit n WHERE n.PermitPK.theName = :theName"),
})
public class Permit implements Serializable {

    private static long serialVersionUID = 1L;

    @EmbeddedId
    private PermitPK PermitPK;

	...

    @ManyToOne
    @JoinColumns({
        @JoinColumn(name = "permittype", referencedColumnName = "permittype", insertable = false, updatable = false)
    })
    private PermitType permitType;

	...

}


My Payara instance is on my local machine, but the database is connected to over a VPN. I deployed the war file to my Payara server, and I turned on Monitoring for some stuff. Included in the monitoring I turned on was monitoring of JDBC to high. I noticed the following in the output.

...
FINE:   SELECT permittype, permittypedesc FROM fapermittypes WHERE (permittype = ?)
	bind => [GENERAL]
FINE:   SELECT permittype, permittypedesc FROM fapermittypes WHERE (permittype = ?)
	bind => [GENERAL]
FINE:   SELECT permittype, permittypedesc FROM fapermittypes WHERE (permittype = ?)
	bind => [GENERAL]
FINE:   SELECT permittype, permittypedesc FROM fapermittypes WHERE (permittype = ?)
	bind => [GENERAL]
FINE:   SELECT permittype, permittypedesc FROM fapermittypes WHERE (permittype = ?)
	bind => [GENERAL]
FINE:   SELECT permittype, permittypedesc FROM fapermittypes WHERE (permittype = ?)
	bind => [GENERAL]
FINE:   SELECT permittype, permittypedesc FROM fapermittypes WHERE (permittype = ?)
	bind => [GENERAL]
FINE:   SELECT permittype, permittypedesc FROM fapermittypes WHERE (permittype = ?)
	bind => [GENERAL]
...


I realize that the JDBC statement has probably been prepared, and I also realize it is probably reusing the same prepared statement with the parameter being bound to it. The code is retrieving the same object several times from the database. It just seems like a waste of time. Is there a way the program can keep a local cache of the PermitType for just the lifetime of a single method that the entity manager will use to get the PermitType object locally if it exists. If it doesn't exist, retrieve it from the database storing a local copy for future references. The goal is to have it only retrieve from the database once since it can be costly. Something like:

public void process() {
   //  start local cache
   runMyprocesses();
   // stop and clear the local cache


Thank you in advance.
Joe
Re: Caching or Something else [message #1860973 is a reply to message #1860920] Tue, 12 September 2023 14:58 Go to previous message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 44
Registered: December 2021
Member
There is a shared cache by default, so you should see caching with or without that annotation - all it does is change some of the setting for that one class. See https://eclipse.dev/eclipselink/documentation/2.5/jpa/extensions/a_cache.htm#:~:text=The%20EclipseLink%20cache%20is%20an,memory%20to%20minimize%20database%20access for info - I don't think specifying a size with a CacheType.SOFT does anything. Everything gets put in an identity map with Full, soft or weak options with no limit. You might want to look at SOFT_WEAK, the default which maintains a cache with a fixed size using soft references, and weak references on everything else. Also note the named "PermitType.findByName" is incorrect - it has the wrong case for n.permittype which I hope is just a typing mistake when copying. Since this is the same as a findById, the query doesn't seem to be necessary anyway.

As for the duplicate statements: you've filtered out the timestamps and other logs message, so we can't tell how frequently they are occurring or in what contexts. There are many reasons for an object to not be in the shared cache requiring it to be fetched from the database, and there are two levels of caching - the shared cache, and then the 1st level cache (at within the EntityManager or UnitOfWork). If these reads are performed through their own EntityManagers in their own transactions where data modification might have occurred, the shared data cannot be used, and the object is not immediately put in the shared cache so that transactional data doesn't pollute the shared cache. Course, it could be a custom query - something just returning the permitType and permitTypeDescription instead of the managed (and so cached) PermitType entity. You'll have to check out the processes doing the loading and see what settings they are using to determine what can be done to reduce this overhead.

Best Regards,
Chris
Previous Topic:Eclipselink Static weave maven plugin throwing error
Next Topic:Eclipselink with spring giving error while loading descriptor xml
Goto Forum:
  


Current Time: Fri Dec 08 02:23:17 GMT 2023

Powered by FUDForum. Page generated in 0.02169 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top