How to cache Spring Data JPA Projections

2019-05-30 07:31发布

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< UserProfile > as shown

The JPA Projection.

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();

}

The User Entity.

@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<String,String> phonenumbers = new HashMap<String,String>(0);

    @JsonBackReference
    @OneToMany(cascade = CascadeType.ALL, orphanRemoval=true)
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    private List<Address> addresses = new ArrayList<Address>(0);

    //Omitted Getters and Setters 

    @Override
    public int hashCode() {...}

    @Override
    public boolean equals(Object obj) {...}


}

The User repository.

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    public Page<UserProfile> findAllUserProfilesBy(Pageable pageable);

}

The User service implementation.

@Service
@Transactional(readOnly=true)
public class UserServiceImpl implements UserService {

    @Autowired
    UserRepository UserRepository;

    @Override
    @Cacheable("users")
    public Page<UserProfile> findAllUserProfiles(Pageable pageable) {
        //simulateSlowService();
        return UserRepository.findAllUserProfilesBy(pageable);
    }   

}

However I get the following exception when the service method gets called.

java.lang.RuntimeException: Class org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor does not implement Serializable or externalizable

How should I go about caching the result of the service method? Any help is greatly appreciated.

0条回答
登录 后发表回答