Spring data repository's method to find by the field of a field
Asked Answered
C

2

29

I've two entities, a user and a registered user.

A registered user has a field of type user. I would like to have a method in the spring data repository related to this registered user entity to search all registered users by the username of the user that is connected to the registered user.

So, this is the registered user entity with an associated user field:

@Entity
public class RegisteredUser implements Serializable {

    ... 
    @OneToOne
    @JoinColumn(name = "USERNAME_FK")
    private User user;
    ...
}

and this is a user with a username:

@Entity
public class User implements Serializable { 
    ...
    @Id
    @Column(nullable = false)
    protected String username;
    ...
}
Correspondent answered 12/5, 2016 at 17:37 Comment(1)
U are using an onetoone mapping between this 2 entities.. which mean that u cant find lot of users for the same registereduser.. i think u should use onetomany annotationAttorney
H
34

Spring Data (at least 1.12.x version) uses PropertyPath#from method to extract path to a property for a predicate constructed from method name. According to sources it uses underscore as "field separator". So first variant is as follows

public interface RegisteredUserRepository extends CrudRepository<RegisteredUser,String> {
    List<RegisteredUser> findRegisteredUserByUser_Username(String username);
}

There is also code which treat an uppercase char as field separator if whole field name is not found. So if you don't have a userUsername field in RegisteredUser second varian is

public interface RegisteredUserRepository extends CrudRepository<RegisteredUser,String> {
    List<RegisteredUser> findRegisteredUserByUserUsername(String username);
}
Huggins answered 12/5, 2016 at 21:16 Comment(2)
The second option worked (didn't try the first), thanks. By the way, I just wanted to find one registered user (since it's a one-to-one relationship), so the method signature at the end was: findOneRegisteredUserByUserUsername(String username).Correspondent
what should we use for arg if we have a similar property in the main entity? for example, I use id for primary keys in all entities so what should I have to use if I want to find all main entities based on the other entity's id?Mesdames
G
1

You may also simply use a library like this one, which lets you build dynamic filters (supports logical operators, comparators, enums, dates, booleans, joins, functions, and much more): https://github.com/turkraft/spring-filter

You won't have to create any repository interface and you will be able to use the provided query builder in your client app directly.

Example query:

/search?filter= average(ratings) > 4.5 and brand.name in ('audi', 'land rover') and (year > 2018 or km < 50000) and color : 'white' and accidents is empty

Usage:

@GetMapping(value = "/search")
public List<Entity> search(@EntityFilter Specification<Entity> spec, Pageable page) {
  return repo.findAll(spec, page);
}

Don't forget the dependency:

<dependency>
    <groupId>com.turkraft</groupId>
    <artifactId>spring-filter</artifactId>
    <version>0.9.5</version>
</dependency>

You may also check rsql, although it's a bit outdated now https://github.com/jirutka/rsql-parser

Gonad answered 13/4, 2021 at 9:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.