I want to add to an existing entity a new Transient column that doesn't exist in the database and will be calculated when calling a query that fetches the table and fill the new column.
I tried the following:
for the following entity:
A {
@Column
Integer x;
@Transient
Integer y;
}
I want to create a query that returns the result in A object:
query (named readA): select x, 1 from A;
List<A> query = em().createNamedQuery('readA').getResultList();
My approach fails, any suggestions on how that can be done?
Since you want this only for this one query, you should use a DTO projection with a dedicated query. You can make use of the JPQL constructor syntax for this.
Something like the following:
SELECT NEW com.mycompany.package.MyDto(alias.x, 1)
FROM A alias
You need a constructor in that class though that matches the use.
Having said that, I think this is a perfect use case for Blaze-Persistence Entity Views.
Blaze-Persistence is a query builder on top of JPA which supports many of the advanced DBMS features on top of the JPA model. I created Entity Views on top of it to allow easy mapping between JPA models and custom interface defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure the way you like and map attributes(getters) via JPQL expressions to the entity model. Since the attribute name is used as default mapping, you mostly don't need explicit mappings as 80% of the use cases is to have DTOs that are a subset of the entity model.
A projection with Entity Views could look as simple as the following
@EntityView(A.class)
interface MyDto {
long getX();
@Mapping("1") // This is where your JPQL expression goes
int getY();
}
Querying is a matter of applying the entity view to a query, the simplest being just a query by id.
MyDto dto = entityViewManager.find(entityManager, MyDto.class, id);
But the Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
List<MyDto> findAll();