Hi Lukas,
I have seen, that the enumeration org.jooq.Clause has been marked for
deprecation. I use this enumeration as part of an automatic cache
invalidation that I've been written.
The cache I've build caches entity instances based of their class and id
(primary key). Think of a map like this:
Map<Class<IEntity>, Cache<Integer, IEntity>>
So the cache groups entities of the same class and the id is used to get
the cached entity instance.
The cache invalidator is registered as VisitListenerProvider on the
jOOQ-Configuration and uses the following implementation:
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import de.onesense.domain.entity.IEntity;
import org.jooq.Clause;
import org.jooq.Table;
import org.jooq.VisitContext;
import org.jooq.impl.DefaultVisitListener;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* A component to invalidate cached entity instances on demand based on
executed insert, update or delete queries.
*
* The cache invalidator is a visit listener that implements Query rendering
and variable binding lifecycle management in order to allow to implement query
* transformation or custom query processing.
*/
@Component
public class EntityCacheInvalidator extends DefaultVisitListener {
// The set of query clauses that require a cache invalidation.
private final static Set<Clause> INVALIDATION_CLAUSES =
ImmutableSet.of(Clause.DELETE_DELETE, Clause.INSERT_INSERT_INTO,
Clause.UPDATE_UPDATE);
// The mapping between database tables and domain entity classes.
private final static Map<String, List<Class<? extends IEntity>>>
TABLE_MAPPING = ImmutableMap.<String, List<Class<? extends IEntity>>>builder()
//.put(CLIENT.getName(), ImmutableList.of(Client.class))
//...
.build();
// The attached entity cache to trigger invalidation requests.
private EntityCache entityCache;
/**
* Creates a new instance of the cache invalidator and attaches it to the
given entity cache.
*
* @param entityCache The entity cache to attach to.
*/
public EntityCacheInvalidator(final EntityCache entityCache) {
this.entityCache = entityCache;
}
@Override
public void visitEnd(final VisitContext context) {
if (entityCache == null) {
return;
}
// Entity cache must be (partly) invalidated for any query that
modifies data.
// The check for empty data is done to prevent multiple cache
invalidation.
boolean invalidateCache =
Arrays.stream(context.clauses()).anyMatch(INVALIDATION_CLAUSES::contains) &&
context.data().isEmpty();
if (invalidateCache) {
// Check whether the current query part refers to a table.
String tableName = context.queryPart() instanceof Table ? ((Table)
context.queryPart()).getName() : null;
if (tableName != null) {
List<Class<? extends IEntity>> entityClasses =
TABLE_MAPPING.get(tableName);
if (entityClasses != null) {
entityClasses.forEach(entityClass ->
entityCache.invalidate((Class<IEntity>) entityClass));
}
}
}
}
}
As you can see, each SQL insert, update or delete statement will be
analyzed to retrieve all affected tables. Due to the mapping of table to
entity class we can invalidate the cache in a very targeted manner.
What options do I have to make this cache invalidation still work even if
the enumeration org.jooq.Clause is removed in the next major release of
jOOQ?
Thank you for your help.
Kind regards,
Marcus
--
You received this message because you are subscribed to the Google Groups "jOOQ
User Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.