嗨团队,
我正在使用Spring Boot 2.3.12。内部使用Spring Data Redis 2.3.9的版本。作为托管依赖项发布。
当我试图使用Spring Boot CRUD存储库将对象保存到Redis缓存时,它正在毫无错误地存储,我可以通过Redis管理器看到存储的对象。
但是,当我尝试使用相同的id(即使用CRUD repository的findById()方法)获取相同的对象时,我找不到它。
此外,当我在同一个crudepository对象上尝试findAll()时,我得到了可选选项。空结果很奇怪,因为findAll()应该返回存储库中的所有记录。
我在下面添加了配置、存储库和模型类代码以及一些截图供您阅读。
请注意:我知道在这个平台上有很多类似的问题与这个问题有关,我也尝试了这些问题的解决方案,但这对我来说不起作用。
这个问题的任何解决方案都会非常有用。
模型类:
package com.test.cache.entity;
import java.util.concurrent.TimeUnit;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.TimeToLive;
import org.springframework.data.redis.core.index.Indexed;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
@RedisHash("OTPValidationLogCache")
public class OTPValidationLogCache {
@Id
@Indexed
private String id;
@Indexed
private int validationFailureCount;
@TimeToLive(unit = TimeUnit.MILLISECONDS)
private long expiry;
}
存储库:
package com.test.cache.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.test.cache.entity.OTPValidationLogCache;
@Repository
public interface OTPValidationLogCacheRepository extends CrudRepository<OTPValidationLogCache, String> {
}
Redis配置类:
package com.test.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import java.time.Duration;
@Configuration
@EnableRedisRepositories(basePackages = "com.test")
public class RedisConfig {
public static final long REDIS_CONNECT_TIMEOUT_SECS = 10L;
@Bean
public RedisStandaloneConfiguration redisStandaloneConfiguration() {
final RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName("*******");
redisStandaloneConfiguration.setPort(6379);
redisStandaloneConfiguration.setPassword(RedisPassword.of("**********"));
//Credentials hidden for code sharing purpose.
return redisStandaloneConfiguration;
}
@Bean
public JedisConnectionFactory redisConnectionFactory() {
final JedisClientConfiguration jedisClientConfiguration = JedisClientConfiguration.builder()
.connectTimeout(Duration.ofSeconds(REDIS_CONNECT_TIMEOUT_SECS))
.useSsl()
.build();
return new JedisConnectionFactory(redisStandaloneConfiguration(), jedisClientConfiguration);
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory());
return template;
}
}
Redis Manager屏幕截图:
Eclipse IDE-调试屏幕截图:
你需要为你的实体有相同的包,我通过提取一个库并把我的实体放在那里来解决这个问题
你可以在这里找到解释:https://github.com/spring-projects/spring-data-redis/issues/2114
我也向GitHub上的spring data redis repository提出了一个缺陷,但该缺陷被该存储库的一名维护人员关闭,甚至没有发布任何适当的解决方案。他只是提到了一个已经解决的问题,甚至没有发布任何解决方案。以下是与该问题的链接。
https://github.com/spring-projects/spring-data-redis/issues/2130
因此,在做一些研究时,我遇到了一个解决方案,我在这里分享,它在我的案例中起作用。
解决方案是不使用Spring Boot实现的默认CRUD存储库方法,而是编写自己的存储库类,其中包含从Redis缓存存储和获取数据的标准方法。就这样,现在您应该能够在项目中使用存储库方法存储/获取数据。
我在下面贴一个例子以供参考。
自定义存储库接口
package com.test.cache.repository;
import java.io.IOException;
import java.util.Map;
import com.test.cache.entity.OTPValidationLogCache;
public interface OTPValidationLogCacheRepository {
void save(OTPValidationLogCache customer);
OTPValidationLogCache find(Long id);
Map<?,?> findAll() throws IOException;
void update(OTPValidationLogCache customer);
void delete(Long id);
}
自定义存储库接口实现
package com.test.cache.repository;
import java.io.IOException;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.ScanOptions.ScanOptionsBuilder;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.test.cache.entity.OTPValidationLogCache;
import com.test.configuration.AppConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
@Repository
public class OTPValidationLogCacheRepositoryImpl implements OTPValidationLogCacheRepository {
private String key;
private RedisTemplate redisTemplate;
private HashOperations hashOperations;
private ObjectMapper objMapper;
@Autowired
public OTPValidationLogCacheRepositoryImpl(RedisTemplate redisTemplate, ObjectMapper objmapper) {
this.redisTemplate = redisTemplate;
this.objMapper = objmapper;
}
@PostConstruct
private void init() {
hashOperations = redisTemplate.opsForHash();
}
@Override
public void save(OTPValidationLogCache otpvalCache) {
hashOperations.put(key.concat(otpvalCache.getId().toString()), otpvalCache.getId(), otpvalCache);
setExpiryTime(key.concat(String.valueOf(otpvalCache.getId())), AppConfig.getUserBanDurationInSeconds());
}
@Override
public OTPValidationLogCache find(Long id) {
return (OTPValidationLogCache) hashOperations.get(key.concat(String.valueOf(id)), id);
}
@Override
public Map findAll() throws IOException {
Map<Integer, OTPValidationLogCache> values = Maps.newHashMap();
Cursor c = hashOperations.scan(OTPValidationLogCache.class, new ScanOptionsBuilder().match(key.concat("*")).build());
AtomicInteger count = new AtomicInteger(1);
c.forEachRemaining(element ->
{
values.put(count.getAndIncrement(), objMapper.convertValue(element, OTPValidationLogCache.class));
}
);
c.close();
return values;
}
@Override
public void update(OTPValidationLogCache customer) {
hashOperations.put(key, customer.getId(), customer);
}
@Override
public void delete(Long id) {
hashOperations.delete(key, id);
}
private void setExpiryTime(String key, Long timeout)
{
redisTemplate.expire(key, Duration.ofSeconds(timeout));
}
public synchronized void setKey(String key)
{
this.key = key;
}
}
希望这能帮助将来可能遇到这个问题的其他人。
此外,对于这个问题,还有一个选择,那就是切换到不同的库提供商,例如Redisson,但是,我还没有尝试过,所以如果您愿意,您可以尝试并检查。
我试图获取一个列表从数据库和findAll()返回空列表。我有多个jpa存储库,但只有一个不工作。这是代码: 这就是实体: 当我调用product类别epository.findAll()时,它返回空列表,因此我在数据库中有许多条目。谢谢你的帮助!
问题内容: 我正在尝试从存储过程中获取返回值,但它始终返回0。 C#代码 SP 在所有情况下,它都返回0。我不知道问题所在。 问题答案: 我尝试了类似您的代码,并且可以按预期工作。 但是,您的代码中两次调用ExecuteNonQuery。 首次调用时,将按预期插入记录,然后为返回值添加参数并再次执行命令。但是现在记录已存在,并且存储过程始终落在else块中,因此始终返回零。
java java 在TaskServiceImpl.java.FindAll(pageRequest)中返回NULL。我不太熟悉Mockito,想知道用它创建模拟存储库是否会导致问题?当我这样做时,它工作得很好。findall()没有分页。我使用PagingAndSortingRepository中的findAll(Pageable)方法有问题吗?谢了!
我正在尝试使用JpaRepository、spring boot和mysql发布文章 我有一张像这样的桌子 每当我尝试保存数据时,无论我传递什么值,列user总是0。 存储库如下所示 控制器如下所示
问题内容: 在我的创建表脚本中,我已将hasMultipleColors字段定义为BIT: 运行INSERT时,不会对此字段或其他BIT字段引发警告,但是选择行将显示所有BIT值均为空白。 从命令行手动尝试更新这些记录会产生奇怪的效果-显示该记录已匹配并已更改(如果适用),但始终显示为空白。 服务器版本:5.5.24-0ubuntu0.12.04.1(Ubuntu) 有什么想法吗? 问题答案: 您
我为此使用了一个服务类,但为了最小的可重复示例而删除了它。目前findAll()正在返回一个空数组,而它应该从h2返回一个带有员工实体json的数组。我仍然不清楚Spring如何将数据处理到h2数据库中,所以我想这可能是我的问题的根源。 控制器: 存储库: 实体: 数据sql: schema.sql: