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.

Reply via email to