Spring @Cacheable методы со списками

Я использую последнюю версию Ehcache в своем приложении Spring 4.1.4. Что у меня есть:

class Contact{
    int id;
    int revision;
}    

@Cacheable("contacts")
public List<Contact> getContactList(List<Integer> contactIdList) {
    return namedJdbc.queryForList("select * from contact where id in (:idlist)", Collections.singletonMap("idlist", contactIdList));
}

@CachePut(value="contact", key = "id")
public void updateContact(Contact toUpdate) {
    jdbctemplate.update("update contact set revision = ? where id = ?", contact.getRevision(), contact.getId());
}

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

Я использую простой Spring JDBC и Ehcache, не JPA и не Hibernate.

1 ответ

Работал у меня. Вот ссылка на мой ответ. /questions/19524109/spring-cachejsr107-argument-listcollection-kak-chast-klyucha/55404654#55404654

TL:DR

@Cacheable(cacheNames = "test", key = "#p0")
public List<String> getTestFunction(List<String> someIds) {

подробнее о моем окружении в ответе.

Не думай, что это возможно. List<Integer> будет ключом против возвращаемого значения getContactList будут сохранены в кеше.

Так что, если список идентификаторов, которые вводятся в ваш getContactList содержит точно такие же идентификаторы, как и в одном из предыдущих вызовов, это будет пропуск кэша и данные будут извлечены из БД. (ПРИМЕЧАНИЕ: два списка считаются равными, если они точно содержат одинаковые элементы и в одинаковом порядке)

Одним из вариантов является изменение вашего метода getContactList(List<Integer> contactIdList) в getContact(Integer id) - в этом случае создание кеша может занять некоторое время, но как только контакт для данного идентификатора окажется в кеше, БД не будет использоваться для его повторного извлечения в будущих вызовах.

Хотя это и не элегантно, но другой вариант - сделать кэширование вручную в getContactList метод.

Другие вопросы по тегам