Projections
Learn to use Projections to customize a part of the entity class.
Use Projections when the required result is a subset of an entity, that is when the required result is 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.
Example 2-6 Using Projections
The following example defines projections in the context of
Student entity class. See 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
StudentViewand 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; } } - You can use the new types (
StudentViewandStudentProjection) as the result of the custom find methods in theStudentRepositoryclass.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 must contain duplicates. If these duplicates are not required then you can use the
Distinctkeyword to eliminate them as follows: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_lastNamedeclare $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_lastNameNote:
Only interface and class based projections that contain a subset of entity properties are supported by Oracle NoSQL Database SDK for Spring Data. Projections using@Valueannotations are not supported. Dynamic projections, when return type is parametrized, are also not supported. - Modify the
runmethod and call 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 Accessing Oracle NoSQL Database Using Spring Data Framework to get more details on theAppConfigclass to provide the connection details of the database and theAppclass that implements therunmethod and has themainmethod. - 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