Projections
Use Projections when the required result is a subset of an entity, that is when the required result is just a small part of the entity. You can define an interface or a POJO class with a subset of the properties found in the entity class. Then you use these interfaces or POJO classes as the parametrized type result of the custom repository methods.
Examples
Student
entity class. See Example: Accessing Oracle NoSQL Database Using Spring Data Framework to get the details on creating the Student
entity
class and the StudentRepository
interface.
- Define an interface
StudentView
and a POJO classStudentProjection
.public interface StudentView { String getLastName(); }
public class StudentProjection { private String firstName; private String lastName; public StudentProjection(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
- The new types (
StudentView
andStudentProjection
) can be used as the result of the custom find methods in theStudentRepository
class.import java.util.Date; import com.oracle.nosql.spring.data.repository.NosqlRepository; public interface StudentRepository extends NosqlRepository<Student, Long> { Iterable<Student> findByLastName(String lastname); Iterable<Student> findByCreatedAtBetween(Date start, Date end); Iterable<StudentView> findAllByLastName(String lastName); Iterable<StudentProjection> getAllByLastName(String lastName); }
Since these results contain a subset of the row, if the Id property is not included the returned set could contain duplicates. If these duplicates are not required then you can use the
Distinct
keyword to eliminate them.Example:List<StudentView>findAllDistinctByLastName(String lastName); List<StudentProjection> getAllDistinctByLastName(String lastName);
These methods will generate the following queries:declare $p_lastName String; select distinct {'lastName': t.kv_json_.lastName} as kv_json_ from Student \ as t where t.kv_json_.lastName = $p_lastName
declare $p_lastName String; select distinct {'firstName': t.kv_json_.firstName, 'lastName': t.kv_json_.lastName} as kv_json_ \ from Student as t where t.kv_json_.lastName = $p_lastName
Note:
Only interface and class based projections that contain a subset of entity properties are supported by NoSQL SDK for Spring Data. Projections using @Value annotations are not supported. Dynamic projections, when return type is parametrized, are also not supported. - Modify the
run
method and invoke the custom methods (defined with Projection interface and POJO Class).// Using projection interface System.out.println("\n With projection findAllByLastName: Smith"); repo.findAllByLastName("Smith") .forEach(c -> System.out.println("StudentView :" + c)); // using projection POJO class here System.out.println("\n With projection getAllByLastName: Smith"); repo.getAllByLastName("Smith") .forEach(c -> System.out.println("StudentProjection.firstName :" + c.getFirstName() + " StudentProjection.lastName :" + c.getLastName() ));
Note:
See Example: Accessing Oracle NoSQL Database Using Spring Data Framework to get more details on theAppConfig
class to provide the connection details of the database and theApp
class that implements therun
method and has themain
method. - Run the program from the runner class. You will get the
following
output.
With projection findAllByLastName: Smith StudentView :Student{id=0, firstName='null', lastName='Smith', createdAt='null'} With projection getAllByLastName: Smith StudentProjection.firstName :John StudentProjection.lastName :Smith