无法在 Spring Boot 中使用 Crud Repository 从 Redis 获取结果?

Posted

技术标签:

【中文标题】无法在 Spring Boot 中使用 Crud Repository 从 Redis 获取结果?【英文标题】:Unable to get result from the Redis using Crud Repository in Spring Boot? 【发布时间】:2019-04-06 21:05:06 【问题描述】:

我正在开发 Spring Boot + Redis 示例。我从链接中获取了参考:https://www.baeldung.com/spring-data-redis-tutorial。在此示例中,我开发了存储库方法 Student findByNameAndGender(String name, Gender gender); 甚至是 Student findByName(String name);,但在这两种情况下我都没有得到任何结果。?

有什么快速的帮助吗? Redis 查询 -

redis 127.0.0.1:6379> KEYS *
1) "Student"
2) "Student:bb4df14a-7f42-4fc3-b608-fc4b7d45109e"
3) "Student:69affaa4-e56c-49e3-9ef4-1cd7509d299b"
redis 127.0.0.1:6379>

Student.java

@Data
@AllArgsConstructor
@Builder
@NoArgsConstructor
@RedisHash("Student")
public class Student 
    public enum Gender 
        MALE, FEMALE
    

    private String id;
    private String name;
    private Gender gender;
    private int grade;

StudentRepository.java

@Repository
public interface StudentRepository extends CrudRepository<Student, String>
    Student findByNameAndGender(String name, Gender gender);

RedisConfig.java

@Configuration
@EnableRedisRepositories
public class RedisConfig 
    @Bean
    JedisConnectionFactory jedisConnectionFactory() 
        return new JedisConnectionFactory();
    
    @Bean
    public RedisTemplate<String, Object> redisTemplate() 
        final RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(jedisConnectionFactory());
        template.setValueSerializer(new GenericToStringSerializer<Object>(Object.class));
        return template;
    

SpringDataRedisEugenpApplication.java

@SpringBootApplication
public class SpringDataRedisEugenpApplication implements CommandLineRunner

    @Autowired
    private StudentRepository repository;

    public static void main(String[] args) 
        SpringApplication.run(SpringDataRedisEugenpApplication.class, args);
    

    @Override
    public void run(String... args) throws Exception 
        repository.save(Student.builder().name("John").gender(Student.Gender.MALE).grade(1).build());
        repository.save(Student.builder().name("Michael").gender(Student.Gender.MALE).grade(2).build());

        Iterable<Student> students = repository.findAll();
        for (Student student : students) 
            System.out.println("=============================");
            System.out.println("Details ? "+student.toString());
        

        Student s = repository.findByNameAndGender("John", Student.Gender.MALE);
        System.out.println("Student ="+s.toString());  //line-34
    

错误 -

java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:795) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:776) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    at com.baeldung.SpringDataRedisEugenpApplication.main(SpringDataRedisEugenpApplication.java:19) [classes/:na]
Caused by: java.lang.NullPointerException: null
    at com.baeldung.SpringDataRedisEugenpApplication.run(SpringDataRedisEugenpApplication.java:34) [classes/:na]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:792) [spring-boot-2.0.6.RELEASE.jar:2.0.6.RELEASE]
    ... 5 common frames omitted

很少的查询 -

1)如何查看redis中实际存储的数据?

2)我们如何控制Id从一个开始?

edis 127.0.0.1:6379> get Student:1
(error) ERR Operation against a key holding the wrong kind of value
redis 127.0.0.1:6379> get Student:2
(error) ERR Operation against a key holding the wrong kind of value
redis 127.0.0.1:6379>

我真的很难看到

redis 127.0.0.1:6379> mget Student:1
1) (nil)
redis 127.0.0.1:6379> mget Student:2
1) (nil)
redis 127.0.0.1:6379> mget Student
1) (nil)

【问题讨论】:

34 在你的SpringDataRedisEugenpApplication 类中是哪一行? 【参考方案1】:

我自己能够找出以下问题的答案。

您只需将@Index 注释放在字段级别。 @Index 注释将该属性标记为用于索引,它使用 Redis @literal SET 来跟踪具有匹配值的对象。

@Indexed
private String name;

@Ref:https://scalegrid.io/blog/introduction-to-redis-data-structures-hashes/

1) 如何查看redis中实际存储的数据?

redis 127.0.0.1:6379> hgetall Student:1
 1) "_class"
 2) "com.baeldung.spring.data.redis.model.Student"
 3) "id"
 4) "1"
 5) "name"
 6) "John Doe"
 7) "gender"
 8) "MALE"
 9) "grade._class"
10) "java.lang.Integer"
11) "grade"
12) "1"

redis 127.0.0.1:6379> hgetall Student:2
 1) "_class"
 2) "com.baeldung.spring.data.redis.model.Student"
 3) "id"
 4) "2"
 5) "name"
 6) "Michael Harford"
 7) "gender"
 8) "MALE"
 9) "grade._class"
10) "java.lang.Integer"
11) "grade"
12) "2"

【讨论】:

您是否在名称和性别字段中添加了@Index 注释?我可以把它们放到 id 字段中吗? @mertaksu - 是的,你可以这样做,如果你这样做,你可以看到已经为它创建了单独的索引数据结构 不适合我。尝试了几乎所有关于 SO 的建议。我正在使用 redis 服务器版本 6.0.9 和 spring-boot 2.3.5。我有一个类用户和另一个类地址。用户有一个地址列表。我没有用任何东西注释地址。但是将 @Indexed 放在 User 类中的属性“名称”上。使用 CrudRepository findByName() 时我得到空值。这可能是什么原因。

以上是关于无法在 Spring Boot 中使用 Crud Repository 从 Redis 获取结果?的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot crud 和 swagger使用

是否可以在不使用 Spring Boot JPA 的情况下测试基于 java 的 CRUD?

Spring boot整合mybaties+thymeleaf实现基础crud

Spring boot 入门三:spring boot 整合mybatis 实现CRUD操作

spring boot使用mongodb时,xxxRepository不能Autowired的问题

带有软删除的 Spring Boot GET 方法如何在服务 impl 中添加另一个异常