Spring Data ClassCastException in Class Projection

Viewed 138

I am trying to do a class projection with Spring Data. It should be working as the requirement is "the parameter names of its constructor must match properties of the root entity class." and it matches. But for whatever reason, it throws an exception:

java.lang.ClassCastException: class ws.xx.posts.post.PostSnapshot cannot be cast to class ws.xx.posts.post.dto.query.PostDetailsQueryDTO (ws.xx.posts.post.PostSnapshot and ws.xx.posts.post.dto.query.PostDetailsQueryDTO are in unnamed module of loader 'app')

It is worth noting that the Entity is in 'posts-domain' module and DTO is in 'posts-app' module. I've already tried doing it manually without Lombok but the result is the same it throws an exception.

Entity (It is configured in separate file orm.xml, this is its value object):

@EqualsAndHashCode
@ToString
@Getter(value = PACKAGE)
@NoArgsConstructor(access = PROTECTED)
@AllArgsConstructor(access = PACKAGE)
class PostSnapshot {

    private Long id;

    private UUID postId;
    private UUID ownerId;

    private String title;
    private String description;

    private ZonedDateTime createDate;
}

DTO:

@Builder(toBuilder = true)
@EqualsAndHashCode
@ToString
@Getter
@AllArgsConstructor
public class PostDetailsQueryDTO implements Serializable {
    
    private UUID postId;
    private UUID ownerId;

    private String title;
    private String description;

    private ZonedDateTime createDate;
}

QueryRepository:

interface SqlPostQueryRepository extends PostQueryRepository, Repository<PostSnapshot, Long> {
    @Override
    PostDetailsQueryDTO findByPostId(UUID postId);

    @Override
    Page<PostDetailsQueryDTO> findAll(Pageable pageable);
}
1 Answers

Try defining your repository method as:

@Override
<T> T findByPostId(UUID postId, Class<T> type);

@Override
<T> Page<T> findAll(Pageable pageable, Class<T> type);

and pass PostDetailsQueryDTO.class as second parameter in your method calls.

I Just had a similar error for the first time an hour ago (with a projection interface), and this workaround saved me, though I still have no idea of the root cause.

Related