I'm updating some Spring Boot Applications with JPA queries. Everything works fine except from one specific kind of queries (findByJsonNode
). This worked fine in earlier versions, but after I upgraded my beans can't be created.
It worked fine up to Spring Boot 2.1.4.RELEASE
and spring cloud version Greenwich.SR1
, but when I upgrade to Spring Boot 2.2.4.RELEASE
and spring cloud version Hoxton.RELEASE
, Spring can't create my repository bean.
Caused by: java.lang.IllegalStateException: Operator SIMPLE_PROPERTY on searchDto requires a scalar argument, found class com.fasterxml.jackson.databind.JsonNode in method public abstract se.company.search.Search se.company.search.SearchRepository.findFirstBySearchDto(com.fasterxml.jackson.databind.JsonNode).
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.throwExceptionOnArgumentMismatch(PartTreeJpaQuery.java:171)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.validate(PartTreeJpaQuery.java:147)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:90)
... 73 common frames omitted.
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.throwExceptionOnArgumentMismatch(PartTreeJpaQuery.java:171) ~[spring-data-jpa-2.2.4.RELEASE.jar:2.2.4.RELEASE]
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.validate(PartTreeJpaQuery.java:147) ~[spring-data-jpa-2.2.4.RELEASE.jar:2.2.4.RELEASE]
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:90) ~[spring-data-jpa-2.2.4.RELEASE.jar:2.2.4.RELEASE]
... 74 common frames omitted
The repository class looks like below
@Repository
public interface SearchRepository extends PagingAndSortingRepository<Search, String> {
Search findFirstBySearchDto(JsonNode searchDto);
}
Entity
/**
* Entity for saving as search
*
* Users can save searches and every search will be stored in history for reference
*/
@Slf4j
@Data
@Entity(name = "search")
@Table(name = "tt_searches", indexes = {
@Index(columnList = "searchDto", name = "searchdto_hidx")
})
@TypeDef(
name = "json-node",
typeClass = JsonNodeStringType.class
)
@EqualsAndHashCode(exclude = { "id", "savedSearches", "searchHistory" })
public class Search {
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().findAndRegisterModules();
public Search() {
}
public Search(SearchDto searchDto, List<SavedSearch> savedSearches, List<SearchHistory> searchHistory) {
this.searchDto = OBJECT_MAPPER.valueToTree(searchDto);
this.savedSearches = savedSearches;
this.searchHistory = searchHistory;
}
public Search(JsonNode searchDto, List<SavedSearch> savedSearches, List<SearchHistory> searchHistory) {
this.searchDto = searchDto;
this.savedSearches = savedSearches;
this.searchHistory = searchHistory;
}
@Id
@Column(columnDefinition = "CHAR(36)")
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private String id;
@Type(type = "json-node")
@Column(columnDefinition = "VARCHAR(2000)", unique = true)
private JsonNode searchDto;
@OneToMany(mappedBy = "search", fetch = FetchType.LAZY)
@OrderBy("name DESC")
@JsonIgnore
private List<SavedSearch> savedSearches;
@OneToMany(mappedBy = "search", fetch = FetchType.LAZY)
@OrderBy("timestamp DESC")
@JsonIgnore
private List<SearchHistory> searchHistory;
public SearchDto getSearchDto() {
try {
return OBJECT_MAPPER.treeToValue(searchDto, SearchDto.class);
} catch (JsonProcessingException e) {
log.error("Could not convert JsonNode to SearchDto when retrieving data from entity: {}", this.id);
return null;
}
}
public void setSearchDto(SearchDto searchDto) {
this.searchDto = OBJECT_MAPPER.valueToTree(searchDto);
}
}
I encountered this same problem. I worked around it by changing the name of my method by adding "In" to the end of it.
For your example, it would be
findAllByTagsIn(java.util.Set)
See the "supported keywords inside method names" table here: https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation