I have the following projection in my Java (Spring Boot) app:
public interface DemoProjection {
UUID getUuid();
String getName();
String getSurname();
String getLabel();
void setLabel(String label);
I want to set this label
field in my service:
public DemoProjection findAByUuid(UUID uuid) {
// returns a single record
final DemoProjection demo = demoRepository.findAByUuid(uuid);
final String label = String.format(
"Name: %s%nSurnamame Surname: %s",
demo.geteName(),
demo.getSurname());
// ! this line throws error
demo.setLabel(label);
return demo;
}
demo.setLabel(label);
throws error: "cannot set projection A TupleBackedMap cannot be modified."
So, how can I set label
field in the projection?
CodePudding user response:
You can't actually do that. Spring Data uses proxies and AOP to bind the query result to your projection interface, and since it's an interface you can't change that in a magical way. I would suggest creating a model/dto and map your projection values there:
public class DemoDto {
private String uuid;
private String name;
private String surname;
//getters and setters ommited for brevity
}
You can create a DemoDto object with your desired values.
In alternative, you can use a projection class instead of a projection interface. Check spring docs on how to do that :)
CodePudding user response:
Just create a default method in your DemoProjection interface to return getLabel formatted as you wish:
public interface DemoProjection {
UUID getUuid();
String getName();
String getSurname();
default String getLabel() {
return String.format(
"Name: %s%nSurnamame Surname: %s",
geteName(),
getSurname());
}
}
this is required as you can't set a Projection after it has been created by JPA but since you only need formatting there is no need to set anything - default method does the trick.