Spring Data JPA Redis : Cannot write custom method based query
Asked Answered
O

2

6

I have configured Spring Data JPA with Redis and using RedisRepositories with provides methods like find(), findAll() etc. All these methods seem to be working just fine, but I am not able to write my custom method like.

RedisEntity findByGenderAndGrade(String gender, String grade);

RedisEntity is a simple POJO Entity class. If you want any more info, please let me know in messages.

Following is my entity:

@Data
@RedisHash("test1")
public class RedisEntity implements Serializable {

    @Id
    @GeneratedValue
    private String id;
    private String name;
    private String gender;
    private Integer grade;
}

Repository:

@Repository
public interface TestRepository extends JpaRepository<RedisEntity, String> {

    List<RedisEntity> findAllByGender(String gender);
    List<RedisEntity> findAllByGrade(Integer grade);
}

Service/Controller:

        @Override
        public List<RedisEntity> getById(String id) {
            return testRepository.findById(id); //returns data perfectly.
        }
        @Override
        public List<RedisEntity> getAllByGender(String gender) {
            return testRepository.findAllByGender(gender); //returns [] 
        }

        @Override
        public void saveEntity(RedisEntity redisEntity) {
            testRepository.save(redisEntity); // saves it in redis perfectly.
        }

Also, findByGender and findAllByGender both give [], although I can see data in my redis database and save it as well.

As requested by FrançoisDupire,

@Configuration
public class RedisConfig {

    @Autowired
    private DeploymentProperties deploymentProperties;

    private static Logger logger = LoggerFactory.getLogger(RedisConfig.class);

    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration("localhost", 6379);
        redisStandaloneConfiguration.setPassword(RedisPassword.of("root"));
        return new JedisConnectionFactory(redisStandaloneConfiguration);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(jedisConnectionFactory());
        return template;
    }
}

Also, I had referred this article: Baeldung article on Spring data redis

Ojibwa answered 29/6, 2018 at 12:31 Comment(10)
What happens when you call this method? Is there an error? Is a null value retrieved?Wisnicki
I get an empty object in response.Ojibwa
Are gender and grade identifying data? If not you should return a list and not a signle object. Also, but I'm not sure it's mandatory, but I think you must use findOne to return a single entity and findAll to return a collection (must check that though)Wisnicki
show your RedisEntity classFourposter
It seems Spring Data can deduce from the signature if it must return a single or a collection of entities if you use findBy. By using findOneBy and findAllBy you enforce the return of a single entity or a collection.Wisnicki
Is it possible to see your config class?Wisnicki
Sure @FrançoisDupireOjibwa
Thanks @AyushNigam! What happens if you add @EnableRedisRepositories to your configuration class?Wisnicki
You may need to add @Indexed to gender and grade in order for the finds to work.Roof
@JoshJ you save my day thanks dude :)Nelsonnema
O
5

As mentioned by @JoshJ and verified by myself and others, The solution to the problem is:

Adding @Indexed annotation to all those columns/fields which need to be used with all finds.

@Data
@RedisHash("EmployeeDetails")
public class RedisEntity {

 @Id
 private String employeeId;

 private String firstName;

 private String lastName;

 @Indexed
 private String gender;

 @Indexed
 private String grade;

}
Ojibwa answered 20/1, 2021 at 8:32 Comment(0)
W
0

We have the Spring Data Redis Library which provides the scope to write the custom method.Attaching Sample code.

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>2.0.8.RELEASE</version>
</dependency>

Entity Definition

@Data
@RedisHash("EmployeeDetails")
public class RedisEntity {

    @Id
    private String employeeId;

    private String firstName;

    private String lastName;

    private String gender;

    private String grade;

}

Repository Definition

@Repository
public interface RedisEntityRepository extends CrudRepository<RedisEntity, String>{

    List<RedisEntity>  findAllByGenderAndGrade(String gender, String grade);
}

Implementation

@Component
public class RedisEntityImpl implements RedisEntityService {

    @Autowired
    private RedisEntityRepository redisEntityRepository;

    @Override
    public List<RedisEntity> getAllByGenderAndGrade(String gender, String grade) {
        return redisEntityRepository.findAllByGenderAndGrade(gender,grade);
    }
}

Properties

spring.cache.type = redis
spring.redis.host = localhost
spring.redis.port = 6379
Wallford answered 29/6, 2018 at 20:16 Comment(1)
Done the exact same thing, but getting an empty array in response. Although I could save the data using redisEntityRepository.save(redisEntity) and get its response. I can also see the data using Redis client in the Redis database.Ojibwa

© 2022 - 2024 — McMap. All rights reserved.