Search code examples
javaspringhibernatespring-data-jpaspring-data

Converting an @Entity to a projection interface manually


So I've been using Spring Data Repositories most of the time. But I've reached a use-case where I cannot use my Spring Repository to retrieve the entity that I need to return to the client. So I have my class ResourceEntity which is a Spring Data Entity. And I'd like to return this entity as a ResourceProjectioninterface.

@Getter
@Setter
@NoArgsConstructor
@Entity
public class ResourceEntity{
    private Long id;
    private String name;
    private String anotherFieldThatIsNotInTheProjection;
}

public interface ResourceProjection {
    Long getId();
    String getName();
}

Usually with a Spring Repository, I'd define something like that :

public interface ResourceRepository extends PagingAndSortingRepository<ResourceEntity, Long> {
    Optional<ResourceProjection> getById(Long id);
}

In this case I can't use the "automatic proxy" generated by Spring Data to automatically implement my projection with the entity's data.

So my question is : Is there a way to "manually" convert the entity to the projection ?

Another solution I thought of is returning the entity and using Jackson annotations like @JsonIgnore to prevent some of my data to be returned, but that is not optimal with the way my code was written.

Otherwise I can always create a DTO class that will fill up with the data from the Entity. But as I have already created my projection for other purposes, I would like avoid creating a second "DTO".


Solution

  • You can do the projection programmatically in this way:

    import org.springframework.data.projection.ProjectionFactory;
    import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
    
     //... 
      resourceEntity = //find resource
      ProjectionFactory pf = new SpelAwareProxyProjectionFactory();
      ResourceProjection rp = pf.createProjection(ResourceProjection.class, resourceEntity)