There is an entity with CLOB property:
@Entity
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
@Column(columnDefinition = "clob")
@Lob
private String description;
//getters and setters here
}
Now I would like to have a method that can return only part of this class, so here is a projection class:
public interface PersonProjection {
String getLastName();
String getDescription();
}
and the repository:
@Repository
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
@Query(value = "select pe.last_name as lastName, pe.description from person pe where pe.last_name = :lastName", nativeQuery = true)
List<PersonProjection> findAllByLastName(@Param("lastName") String lastName);
}
Using native query in this example is not needed but in my case I would like to call an Oracle's function in the where
clause (JSON_TEXTCONTAINS
to be specific).
Now using this repository in the controller causes:
Could not write JSON: Projection type must be an interface!; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Projection type must be an interface! (through reference chain: java.util.ArrayList[0]->com.sun.proxy.$Proxy103[\"description\"])
Exception seems to be caused because query returns description
field as an instance of java.sql.Clob
interface, but in projection class this field is defined as String
. Exception is not thrown when entity class is used as a return type from repository method (and there description
is also defined as a String
).
Complete project to check this problem can be found here.