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
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; } }
- You can use the new types (
StudentView
andStudentProjection
) 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 must contain duplicates. If these duplicates are not required then you can use the
Distinct
keyword 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_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 Oracle NoSQL Database 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 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 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