Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » L2 cache with OneToMany relationships(L2 cache with OneToMany relationships)
L2 cache with OneToMany relationships [message #1855053] Mon, 26 September 2022 14:09 Go to next message
Hans Pikkemaat is currently offline Hans PikkemaatFriend
Messages: 9
Registered: January 2021
Junior Member
Hi,

I'm using eclipselink 2.7.7 and have two entities with a @OneToMany relation:

public class MyTable {
.
.
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "table")
List<MyAttribute> attributes = new ArrayList<>();
.
.
}

public class MyAttribute {
.
.
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "table_id")
MyTable table;
.
.
}

I'm using the default cache settings which means 2nd level cache is enabled.

If my application now loads MyTable and traverses the MyAttribute child objects then they are loaded into 2nd level cache.

Let's assume there is an external system that can change MyAttribute records in the database. Lets also assume this external system sends event to the main system which evicts the MyAttribute records from the 2nd level cache.
(You could say this is a cache coordination implementation)

When this happens de MyTable object is not evicted so when it is retrieved again it will be loaded from 2nd level cache.

Now it comes: this object already contains the earlier loaded MyAttribute objects which are stale now because they were changed by the external system. But they were evicted from 2nd level cache. What I expected eclipselink to do is: check per MyAttribute object if it is still in the 2nd level cache and if not, query it from the database so effectively refresh the object. But this is not happening, eclipselink simply returns the cached objects !

So it seems that when a MyAttribute object is evicted the MyTable object also should be evicted to prevent issues. But this not desirable because the MyTable object was not changed.

Another solution I tried was to evict the MyTable object (instead of the MyAttribute object) when one of its children got changed but this also caused problems because when the MyTable object got retrieved from the database the MyAttribute objects would still be loaded from 2nd level cache.

Another solution I tried is to configure the MyAttribute as not cacheable and that worked ok but when there are a lot of MyAttribute records then this could become problematic because they will always be queried from the database even when the MyTable object IS cached.

So it seems that caching with parent/child relations is a bit weird and it looks like then should be evicted both when one of then changes.

Am I doing something wrong?

UPDATE:

I tried to create a simple test environment proving this issue but was unsuccessful, my simple application worked fine.

Actually, while debugging, I could see that when I was accessing MyAttribute objects from the cached MyTable object, eclipselink was actually executing an sql query to retrieve the MyAttribute record that was evicted. But the actual data was not being populated into the MyAttribute object itself.

So to be clear, my test application did populate that object.

So the question then is: what could be triggering this behaviour

[Updated on: Mon, 26 September 2022 16:44]

Report message to a moderator

Re: L2 cache with OneToMany relationships [message #1855374 is a reply to message #1855053] Tue, 11 October 2022 08:52 Go to previous messageGo to next message
Hans Pikkemaat is currently offline Hans PikkemaatFriend
Messages: 9
Registered: January 2021
Junior Member
UPDATE:

I found the culprit that is causing the above issue. It happens when caching is enabled selectively and there is an entity with 2 OneToMany relations, of which one of the child objects has @Cacheable(false).

This is clearly a bug.

I created an issue in the github repo: https://github.com/eclipse-ee4j/eclipselink/issues/1728
Re: L2 cache with OneToMany relationships [message #1855855 is a reply to message #1855374] Mon, 07 November 2022 21:27 Go to previous message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 54
Registered: December 2021
Member
Not quite a bug, as this behavior has been a 'feature' of the product from the beginning.

You can get the behavior you seem to want though if you use the @Noncacheable annotation on your reference mapping, forcing EclipseLink to fetch it each time it pulls the parent from the cache. Fetching it implies issuing a query - if it is a OneToMany (a ReadAllQuery), it'll have to go to the database, while for *ToOne relationships (a ReadQuery with a single result expected) it will try to hit the cache and only go to the database if it isn't there. This is probably the behavior you will want, as it will pick up changes on eviction without having to evict all referencing entities.

In many models, when leaf nodes change, it is good practice to evict the roots as well, which might be why this behavior is less known and less documented. And not globally configurable (that would greatly affect performance though).



Previous Topic:Schema changes on application upgrade
Next Topic:Multiple Entity Manager Factories?
Goto Forum:
  


Current Time: Wed Apr 24 15:14:26 GMT 2024

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

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

Back to the top