Отключить Hibernate 2-го уровня кэши во время выполнения - PullRequest
0 голосов
/ 29 марта 2020

Возможно ли отключить кэш 2-го уровня Hibernate для некоторых объектов во время выполнения?

Во многих наших объектах включено кэширование, но я подозреваю, что в некоторых случаях кэш-память не дает больших преимуществ или даже отрицательно влияет на производительность. Я бы хотел поэкспериментировать с различными настройками, не выполняя каждый раз развертывание.

Так как это предназначено только для экспериментов, я не возражаю против решения, которое использует Hibernate Internals или отражение для достижения этой цели.

1 Ответ

0 голосов
/ 01 апреля 2020

Решить это было довольно просто. Следующий код может использоваться для переключения кэша второго уровня для сущностей во время выполнения:

@Slf4j
@UtilityClass
public class HibernateUtil {

    public static void disableCache(EntityManager em, String entityName) {
        toggleCache(em, entityName, false);
    }

    public static void enableCache(EntityManager em, String entityName) {
        toggleCache(em, entityName, true);
    }

    private static void toggleCache(EntityManager em, String entityName, boolean enableCache) {
        final Optional<EntityPersister> persister = getEntityPersister(em, entityName);
        persister.ifPresentOrElse(p -> {
            log.info("Toggling cache for '{}': {}", entityName, enableCache);
            ClassUtil.writeField(p, "canReadFromCache", enableCache);
            ClassUtil.writeField(p, "canWriteToCache", enableCache);
        }, () -> log.warn("Entity '{}' could not be found", entityName));
    }

    private static Optional<EntityPersister> getEntityPersister(EntityManager em, String entityName) {
        final MetamodelImplementor model = (MetamodelImplementor) em.getMetamodel();
        final Collection<EntityPersister> persisters = model.entityPersisters().values();
        return persisters.stream().filter(e -> e.getEntityName().equalsIgnoreCase(entityName))
                .findFirst();
    }
}
...