Hibernate Tips: How to map a view with Hibernate


Take your skills to the next level!

The Persistence Hub is the place to be for every Java developer. It gives you access to all my premium video courses, monthly Java Persistence News, monthly coding problems, and regular expert sessions.


Hibernate Tips is a series of posts in which I describe a quick and easy solution for common Hibernate questions. If you have a question you like me to answer, please leave a comment below.

Question:

How can I map a read-only database view with Hibernate?

Solution:

Database views, in general, are mapped in the same way as database tables. You just have to define an entity that maps the view with the specific name and one or more of its columns.

But the normal table mapping is not read-only, and you can use the entity to change its content.

Depending on the database you use and the definition of the view, you’re not allowed to perform an update on the view content. You should therefore also prevent Hibernate from updating it.

You can easily achieve this with the Hibernate-specific @Immutable annotation which I use in the following code snippet.

@Entity
@Immutable
public class BookView {
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id", updatable = false, nullable = false)
	private Long id;
	@Version
	@Column(name = "version")
	private int version;

	@Column
	private String title;

	@Column
	@Temporal(TemporalType.DATE)
	private Date publishingDate;

	@Column
	private String authors;
	
	...
	
}

The @Immutable annotation tells Hibernate to ignore all changes on this entity, but you can use it to retrieve data from the database.

List<BookView> bvs = em.createQuery("SELECT v FROM BookView v", BookView.class).getResultList();

Learn more:

Views can be a nice way to pre-process the existing data in the database to improve the performance of your application. You can learn more about performance optimizations in my Hibernate Performance Tuning Online Training.

Hibernate Tips Book

Get more recipes like this one in my new book Hibernate Tips: More than 70 solutions to common Hibernate problems.

It gives you more than 70 ready-to-use recipes for topics like basic and advanced mappings, logging, Java 8 support, caching, and statically and dynamically defined queries.

Get it now!

8 Comments

  1. It says “Hibernate-specific @Immutable annotation” but it’s missing the import package:
    import javax.persistence.Entity;

    so you won’t confuse it with javax.persistence.Entity or some other class

  2. Avatar photo MOHAMED AMINE OSMAN says:

    how can i select from view using Spring JPA

    1. Avatar photo Thorben Janssen says:

      If you map the view to an entity, you can use the entity in the same way as any other entity. With Spring Data JPA, you can define a repository for that entity and use its standard methods or define your own derived or custom queries.

  3. Avatar photo Thorben Janssen says:

    Hibernate automatically maps the entity to a table or view with the same name.

  4. Avatar photo Alexandre Ligabue says:

    Hello.

    I created an entity of a mysql view and I am generating list from it, in the inclusions and exclusions the list is updated, however in the editing this does not happen, I need to stop tomcat to load the updated list, I would have some idea about it.

    I’ll be very thankfull.

    Att,
    Alexandre

    1. Avatar photo Thorben Janssen says:

      Did you annotate the entity with @Immutable?
      That tells Hibernate that the entity will never change. So, it excludes it from the dirty checks and never performs an SQL UPDATE for it.

  5. Avatar photo lars.eicher says:

    Thanks for this tip.

    Often views do not provide a unique key that can be used in Hibernate. Currently we add an extra column containing a row_num to our views. This adds some overhead to the query.

    Are there possibilities to create such ids on the fly in Hibernate?

    1. Avatar photo Thorben Janssen says:

      No, there is no easy way for that.
      If you want to map your view to an entity, you need a primary key column. You need to consider that when you define the view.

Comments are closed.