Data Grids
Auto Grid makes it easy to show data from a database in a grid. It works by connecting a JPA repository to a grid component — and with minimal effort. The grid shows columns for all properties of the entity, and loads data in a lazy-loaded manner. It can also provide sorting and filtering.
This guide shows how to set up a JPA entity and repository in the backend, how to expose the repository with a service, and how to connect that service to an Auto Grid in the frontend.
If you don’t have a Hilla project yet, you can quickly create one by running the following command from the CLI:
npx @hilla/cli init my-hilla-app
Setting up the Backend
To use Auto Grid, you need to have JPA and a database in your project. If you haven’t done this already, open the following section on how to configure JPA and an in-memory H2 database. Otherwise, you can skip it.
Database Setup
First, add the following dependencies to the pom.xml
file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
Next, add the following properties to the src/main/resources/application.properties
file:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
First, create a JPA entity class in the backend. For this guide, you’ll use a simple entity that represents a product. Create a Product.java
file next to Application.java
with the following content:
package com.example.application;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import java.time.LocalDate;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String category;
private double price;
private LocalDate dateAdded;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public LocalDate getDateAdded() {
return dateAdded;
}
public void setDateAdded(LocalDate dateAdded) {
this.dateAdded = dateAdded;
}
}
Next, create a Spring JPA repository for the entity. Create a ProductRepository.java
file next to Product.java
with the following content:
package com.example.application;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface ProductRepository extends JpaRepository<Product, Long>, JpaSpecificationExecutor<Product> {
}
Finally, create a service to expose the repository to the frontend. Create a ProductService.java
file next to ProductRepository.java
with the following contents:
package com.example.application;
import com.vaadin.flow.server.auth.AnonymousAllowed;
import com.vaadin.hilla.BrowserCallable;
import com.vaadin.hilla.crud.ListRepositoryService;
@BrowserCallable
@AnonymousAllowed
public class ProductService extends ListRepositoryService<Product, Long, ProductRepository> {
}
This service is annotated with @BrowserCallable
to allow it to be called from the frontend. It extends ListRepositoryService
, which provides a default implementation for fetching paginated, sorted, and filtered data. By default, all services exposed to the frontend are secured and require authentication. To keep things simple, the service has the @AnonymousAllowed
annotation to allow unauthenticated access to the service.
In order to have some example product data, download this SQL script and put it in the src/main/resources
folder:
Creating the View
Now that the backend is set up, you can implement the frontend part. Start by running the application, using the default Maven goal:
mvn
This takes a while to install all necessary dependencies, but once it is done, you should see the application in your browser.
Next, create a view that renders the product data. Create a products.tsx
file in the frontend/views
folder with the following content:
import React from 'react';
import { AutoGrid } from '@vaadin/hilla-react-crud';
import { ProductService } from 'Frontend/generated/endpoints';
import ProductModel from 'Frontend/generated/com/example/application/ProductModel';
export function ProductsView() {
return (
<div className='p-l'>
<AutoGrid service={ProductService} model={ProductModel} />
</div>
);
}
This view renders an Auto Grid component, configured to load data from the ProductService
and using the ProductModel
to define the columns. The ProductModel
is generated from the Product
entity in the backend that you created earlier.
Save the file and open the URL, http://localhost:8080/products
in your browser. You should see a grid like the following, showing product data from the database:
new tab
import { AutoGrid } from '@vaadin/hilla-react-crud';
import { ProductService } from 'Frontend/generated/endpoints';
import ProductModel from 'Frontend/generated/com/vaadin/demo/fusion/crud/ProductModel';
function Example() {
return <AutoGrid service={ProductService} model={ProductModel} />;
}
Further Information
For more information about the Auto Grid feature, see the Auto Grid documentation.