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;
    ...
}
nbro
  • 15,395
  • 32
  • 113
  • 196
  • 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 annotation – FuSsA May 12 '16 at 19:47

2 Answers2

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);
}
Ilya
  • 2,177
  • 15
  • 19
  • 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)`. – nbro May 12 '16 at 21:44
  • 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? – Seyed Ali Roshan Oct 08 '18 at 23:03
0

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

torshid
  • 137
  • 1
  • 9