I'm attempting to create a JPA entity for a view. From the database layer, a table and a view should be the same.
However, problems begin to arise and they are two fold:
When attempting to setup the correct annotations. A view does not have a primary key associated with it, yet without the proper
@javax.persistence.Id
annotated upon a field, you will get anorg.hibernate.AnnotationException: No identifier specified for entity
thrown at Runtime.The Spring Boot
JpaRepository
interface definition requires that theID
type extendsSerializable
, which precludes utilizingjava.lang.Void
as a work-around for the lack of an id on an view entity.
What is the proper JPA/SpringBoot/Hibernate way to interact with a view that lacks a primary key?
I was exploring that topic too. I ended up using Spring Data JPA Interface-based Projections with native queries.
I created an interface, making sure the UPPERCASE part matches the DB Column names:
Then i created a repository, for an Entity (User) not related in any way to the view. In that repository i created a simple native query. vReport1_1 is my view.
About Entity ID mapping
If you can change the view definition, you could use add the rownum as column.
It is generally specific to the DBMS. The idea is to make the row number in the table the id of the entity.
As alternative you could use the a generator of unique id.
UUID
is a possibility. At last you could stick to native SQL while benefiting from JPA/Hibernate to map the native query results to a specific class representing the view data.About Spring Data Repository
If views don't fit naturally into the Spring Data Repository requirements, it probably means that using views instead of tables is not necessary suitable for.
Indeed Spring Data repositories classes such as
CrudRepository
orJpaRepository
are designed to provide out of the box CRUD operations and some additional processing for a specific entity class.The views in terms of DBMS are not included in as you select it but you don't update, insert or delete directly any row from the view.
Besides, what would be the added value to use such Repository beans for a view ? You will use almost nothing of the generated implementation provided by Spring.
In your case if you define the view as an entity I think that using
JpaTemplate
would make more sense.It is just a layer on top of the JPA API.
From the documentation :
If your view doesn't have a candidate key you may add one through the creation query using something like the database UUID function and then use the UUID as the type for the ID the Entity.
If you need to make your Entity read-only you may annotate the fields with
Or annotate you entity class with org.hibernate.annotations.Immutable if your provider is Hibernate >= 5.2.
I hope this helps you, the id you can assign it to a united value in your view.
We map the view to a JPA object as:
We then create a repository: