How to get only selected attributes of an object using Spring JPA?

I am using Spring Boot (1.3.3.RELEASE) and Hibernate JPA in my project. My object is as follows:

@Data @NoArgsConstructor @Entity @Table(name = "rule") public class RuleVO { @Id @GeneratedValue private Long id; @Column(name = "name", length = 128, nullable = false, unique = true) private String name; @Column(name = "tag", length = 256) private String tag; @OneToMany(mappedBy = "rule", cascade = CascadeType.ALL, orphanRemoval = true) private List<RuleOutputArticleVO> outputArticles; @OneToMany(mappedBy = "rule", cascade = CascadeType.ALL, orphanRemoval = true) private List<RuleInputArticleVO> inputArticles; } 

My repository is as follows:

 @Repository public interface RuleRepository extends JpaRepository<RuleVO, Long> { } 

In some cases, I need to get only the id and name attributes of the RuleVO object. How can i achieve this? I found a notification that should be executed using the API and criteria predictions, but how? Thanks in advance. Voitech

+6
source share
4 answers

UPDATE:

As I was told, I am lazy, and it can very well be done, so I update my answer after I look at the website for the correct one.

Here is an example of how to get only the identifier and only the names:

 @Repository public interface RuleRepository extends JpaRepository<RuleVO, Long> { @Query("SELECT r.id FROM RuleVo r where r.name = :name") List<Long> findIdByName(@Param("name") String name); @Query("SELECT r.name FROM RuleVo r where r.id = :id") String findNameById(@Param("id") Long id); } 

We hope you find this update useful.


Old answer:

Only retrieving specific name / id attributes is not possible because it is not the way spring or any SQL database was designed, because you always select a row that is an entity.

What you can do is query on the variables in the entity, for example:

 @Repository public interface RuleRepository extends JpaRepository<RuleVO, Long> { public RuleVo findOneByName(String name); public RuleVo findOneByNameOrId(String name, Long id); public List<RuleVo> findAllByName(String name); // etc, depending on what you want } 

You can change them, but want wrt your needs. You can call these methods directly through the startup repository.

See http://docs.spring.io/spring-data/jpa/docs/current/reference/html/ Section 5.3 for additional parameters and examples.

+8
source

You can do this using the @Query (HQL) annotation.

Refer to the Spring docs below:

http://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query

(find @Query in a Spring doc)

+2
source

Yes, you can achieve this with forecasts. You have many ways to use them:

If you can upgrade to Spring Data Hopper, it provides convenient forecast support. Learn how to use them in the reference documentation .

Otherwise, first create a DTO with the attributes you want to load, for example:

 package org.example; public class RuleProjection { private final Long id; private final String name; public RuleProjection(Long id, String name) { this.id = id; this.name = name; } public Long getId() { return id; } public String getName() { return name; } } 

Of course, you can also use Lombok annotations.

Then you can use in JPQL queries, for example:

 select new org.example.RuleProjection(rule.id, rule.name) from RuleVO rule order by rule.name 

Another option, if you want to avoid using DTO class names in your queries, is to implement your own query method using QueryDSL. With Spring JPA data, you should:

  • Create a new interface using the new method. Example:

     public interface RuleRepositoryCustom { public List<RuleProjection> findAllWithProjection(); } 
  • Modify your repository to expand the new interface. Example:

     public interface RuleRepository extends JpaRepository<RuleVO, Long>, RuleRepositoryCustom { ... 
  • Create a custom repository implementation using JPA support. You must pre-generate Q clases QueryDSL using its Maven plugin. Example:

     public class RuleRepositoryImpl { public List<RuleProjection> findAllWithProjection() { QRuleVO rule = QRuleVO.ruleVO; JPQLQuery query = getQueryFrom(rule); query.orderBy(rule.name.asc()); return query.list(ConstructorExpression.create(RuleProjection.class, rule.id, rule.name)); } } 
+2
source

You can also define a custom constructor to retrieve specific columns using JPQL.

Example:

Replace the {javaPackagePath} full path of the java class package to use as a constructor in JPQL.

 public class RuleVO { public RuleVO(Long id, String name) { this.id = id; this.name = name; } } @Repository public interface RuleRepository extends JpaRepository<RuleVO, Long> { @Query("SELECT new {javaPackagePath}.RuleVO(r.id, r.name) FROM RuleVo r where r.name = :name") List<RuleVO> findIdByName(@Param("name") String name); } 
0
source

All Articles