Description
I have used Spring Data JPA DTO interface-based projection many times and it worked just fine.
But yesterday I came across an interesting issue that is happening only under certain specific combination such as follows:
I have a BaseEntity
as follows:
@MappedSuperclass
class BaseEntity {
@Column(name = "created_at")
protected LocalDateTime createdAt;
@PrePersist
void prePersist() {
createdAt = LocalDateTime.now();
}
//setter & getter
}
I have a JPA entity Post
extending BaseEntity
class as follows:
@Entity
@Table(name = "posts")
public class Post extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "title", nullable = false, length = 150)
private String title;
@Column(name = "slug", nullable = false, unique = true)
private String slug;
@Column(name = "content", nullable = false)
private String content;
//setters & getters
}
I have created a Interface Projections as follows:
public interface PostProjection {
Long getId();
String getTitle();
String getSlug();
String getContent();
LocalDateTime getCreatedAt();
}
Now I have PostRepository as follows:
public interface PostRepository extends JpaRepository<Post, Long> {
List<PostProjection> findAllBy();
@Query("from Post")
List<PostProjection> findAllPosts();
}
The problem: When I get List<PostProjection>
by calling postRepository.findAllBy()
, everything is working fine. But when I get List<PostProjection>
by calling postRepository.findAllPosts()
and then try to access postProjection.getCreatedAt()
method then it is throwing the following Exception:
**java.lang.IllegalStateException: Invoked method is not a property accessor**
at org.springframework.data.projection.PropertyAccessingMethodInterceptor.invoke(PropertyAccessingMethodInterceptor.java:66) ~[spring-data-commons-3.4.0.jar:3.4.0]
at org.springframework.data.projection.ProjectingMethodInterceptor.invoke(ProjectingMethodInterceptor.java:71) ~[spring-data-commons-3.4.0.jar:3.4.0]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.0.jar:6.2.0]
at org.springframework.data.projection.ProxyProjectionFactory$TargetAwareMethodInterceptor.invoke(ProxyProjectionFactory.java:243) ~[spring-data-commons-3.4.0.jar:3.4.0]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.2.0.jar:6.2.0]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:223) ~[spring-aop-6.2.0.jar:6.2.0]
at jdk.proxy2/jdk.proxy2.$Proxy123.getCreatedAt(Unknown Source) ~[na:na]
Observations:
- This Exception is occurring only when I access methods from super class(
BaseEntity
) - This Exception is occurring only when I use
@Query("...")
Here is a minimal reproducer: https://github.com/siva-attic/spring-data-jpa-projection-issue