title: How to cache Spring Data JPA Projections
body: <p>I am running Spring Boot 1.5.1 with Spring Data JPA repositories. I have added a method to my User repository that makes use of JPA projections(UserProfile) which works great. I now wish to cache the results of that method in my Service layer which should return a result of type Page&lt; UserProfile > as shown</p>
  
  <p>The JPA Projection.</p>
  
  <pre><code>public interface UserProfile extends Serializable {
  
      long getId();
  
      @Value("#{target.firstname} #{target.othernames}")
      String getFullName();
  
      String getFirstname();
  
      String getOthernames();
  
      String getGender();
  
      String getEnabled();
  
      @Value("#{T(System).currentTimeMillis()-target.birthday.getTime()}")
      long getBirthday();
  
  }
  </code></pre>
  
  <p>The User Entity.</p>
  
  <pre><code>@Entity
  @Cacheable(true)
  @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
  public class User implements Serializable {
  
      private static final long serialVersionUID = 6756059251848061768L;
  
      @Id
      @GeneratedValue(strategy=GenerationType.AUTO)
      private long id;        
      @Column
      private String firstname;       
      @Column
      private String othernames;
      @Column
      private String gender;
      @Column
      private String photoname;
      @Column
      private Date birthday;
      @Column
      private String username;
      @Column
      private Boolean enabled;
      @Column 
      private String password;
  
      @ElementCollection
      private Map&lt;String,String&gt; phonenumbers = new HashMap&lt;String,String&gt;(0);
  
      @JsonBackReference
      @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true)
      @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
      private List&lt;Address&gt; addresses = new ArrayList&lt;Address&gt;(0);
  
      //Omitted Getters and Setters 
  
      @Override
      public int hashCode() {...}
  
      @Override
      public boolean equals(Object obj) {...}
  
  
  }
  </code></pre>
  
  <p>The User repository.</p>
  
  <pre><code>@Repository
  public interface UserRepository extends JpaRepository&lt;User, Long&gt; {
  
      public Page&lt;UserProfile&gt; findAllUserProfilesBy(Pageable pageable);
  
  }
  </code></pre>
  
  <p>The User service implementation.</p>
  
  <pre><code>@Service
  @Transactional(readOnly=true)
  public class UserServiceImpl implements UserService {
  
      @Autowired
      UserRepository UserRepository;
  
      @Override
      @Cacheable("users")
      public Page&lt;UserProfile&gt; findAllUserProfiles(Pageable pageable) {
          //simulateSlowService();
          return UserRepository.findAllUserProfilesBy(pageable);
      }   
  
  }
  </code></pre>
  
  <p>However I get the following exception when the service method gets called.</p>
  
  <pre><code>java.lang.RuntimeException: Class org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor does not implement Serializable or externalizable
  </code></pre>
  
  <p>How should I go about caching the result of the service method?
  Any help is greatly appreciated.</p>