How to not return an specific column using PagingAndSortingRepository

好久不见. 提交于 2019-12-10 11:27:26

问题


I know the title may sound a bit confusing, but I did not know how to summarize my problem on the title.

My main problem is that I do not want to return an specific column using PagingAndSortingRepository. Imagine the following scenario:

I have two entitys, one called Users:

@Entity
@Table(name = "users")
public class User implements Serializable {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @NotBlank()
  @Column(name = "name")
  private String name;

  @Column(name = "password")
  private String password;

}

And one called Cars:

@Entity
@Table(name = "car")
public class Car implements Serializable {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @NotBlank()
  @Column
  private String name;

  @ManyToOne(targetEntity = User.class, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
  @JoinColumn(name = "owner_id", referencedColumnName = "id")
  private User owner;

}

I want to return a list of car by user's name using PagingAndSortingRepository. Using the following interface I can achieve that:

public interface CarRepository extends PagingAndSortingRepository<Car, Long> {

  List<Car> findByOwner_name(String name);

}

However, with said interface the result will also return the user's password on it. I could use a for on each element of the list and set the password as null, but it would be troublesome in a scenario where there is a user with lots of cars. How could I make it so that the result of the list come with the specific column, password, without any value to the user?

Thanks in advance =).

ps: I thought about returning a list of projection instead of a list of Car, but I do not know how to say it to the projection that just one attribute from the class should be null.


回答1:


You need to use Projections for this purpose. It is documented in detail here

Create an interface with fields you want to include in the entity to be returned.
For example, in your case it would be like this

interface CarSummary {

  String getName();
  Long getId();
  UserSummary getUser();

  interface UserSummary {
    String getName();
    Long getId();
  }
}

and modify your repository like this

public interface CarRepository extends PagingAndSortingRepository<Car, Long> {
    Collection<CarSummary> findByOwner_name(String name);  
}



回答2:


Projections can be used recursively. Something like this should work:

interface CarPojection{

      Long getId();
      String getName();
      UserSummary getUser();

      interface UserSummary {
        Long getId();
        String getName();
      }
    }

And your repository should return CarPojection Find more information in Spring docs: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections




回答3:


You can return a subset of data by providing a matching constructor in your entity class.

@Query("select new com.foo.bar.entity.User(u.id, u.name) from User u where u.name = ?1")
List<User> findByOwner_name(String name);

In you class User just provide the constructor and other properties will be left null:

public User(Long id, String name) {
    // ...       
}


来源:https://stackoverflow.com/questions/48666651/how-to-not-return-an-specific-column-using-pagingandsortingrepository

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!