JPA/SpringBoot Repository for database view (not table)
1. Create View with native SQL in the database,
create or replace view hunters_summary as
select
em.id as emp_id, hh.id as hh_id
from employee em
inner join employee_type et on em.employee_type_id = et.id
inner join head_hunter hh on hh.id = em.head_hunter_id;
2. Map that, View to an 'Immutable Entity'
package inc.manpower.domain;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Subselect;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Date;
@Entity
@Immutable
@Table(name = "`hunters_summary`")
@Subselect("select uuid() as id, hs.* from hunters_summary hs")
public class HuntersSummary implements Serializable {
@Id
private String id;
private Long empId;
private String hhId;
...
}
3. Now create the Repository with your desired methods,
package inc.manpower.repository;
import inc.manpower.domain.HuntersSummary;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import javax.transaction.Transactional;
import java.util.Date;
import java.util.List;
@Repository
@Transactional
public interface HuntersSummaryRepository extends PagingAndSortingRepository<HuntersSummary, String> {
List<HuntersSummary> findByEmpRecruitedDateBetweenAndHhId(Date startDate, Date endDate, String hhId);
}
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:
public interface R11Dto {
String getTITLE();
Integer getAMOUNT();
LocalDate getDATE_CREATED();
}
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.
public interface RaportRepository extends JpaRepository<User, Long> {
@Query(nativeQuery = true, value = "SELECT * FROM vReport1_1 ORDER BY DATE_CREATED, AMOUNT")
List<R11Dto> getR11();
}
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:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Entity
@Table(name = "my_view")
public class MyView implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name = "my_view_id")
private Long myViewId;
@NotNull
@Column(name = "my_view_name")
private String myViewName;
}
We then create a repository:
import org.springframework.data.jpa.repository.JpaRepository;
public interface MyViewRepository extends JpaRepository<View, Long> {
}