JPA/SpringBoot Repository for database view(不是表)

2022-09-01 09:26:18

我正在尝试为视图创建一个 JPA 实体。在数据库层中,表和视图应该是相同的。

但是,问题开始出现,它们是双重的:

  1. 尝试设置正确的批注时。视图没有与之关联的主键,但是如果没有对字段进行适当的注释,您将在运行时得到一个抛出。@javax.persistence.Idorg.hibernate.AnnotationException: No identifier specified for entity

  2. Spring Boot 接口定义要求类型扩展 ,这排除了在视图实体上缺少 id 的解决方法。JpaRepositoryIDSerializablejava.lang.Void

与缺少主键的视图进行交互的正确JPA/SpringBoot/Hibernate方式是什么?


答案 1

我也在探索这个话题。我最终在原生查询中使用了基于Spring Data JPA接口的投影

我创建了一个接口,确保大写部分与数据库列名称匹配:

public interface R11Dto {

   String getTITLE();

   Integer getAMOUNT();

   LocalDate getDATE_CREATED();
}

然后,我为实体(用户)创建了一个存储库,该实体(用户)与视图没有任何关系。在该存储库中,我创建了一个简单的本机查询。vReport1_1是我的观点。

public interface RaportRepository extends JpaRepository<User, Long> {

   @Query(nativeQuery = true, value = "SELECT * FROM vReport1_1 ORDER BY DATE_CREATED, AMOUNT")
   List<R11Dto> getR11();

}

答案 2

1. 在数据库中使用本机 SQL 创建视图,

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.将其映射到“不可变实体”

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. 现在使用所需的方法创建存储库,

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);
}

推荐