如何在 JpaRepository 中为多对一映射实体编写查询
Posted
技术标签:
【中文标题】如何在 JpaRepository 中为多对一映射实体编写查询【英文标题】:How to write query for many to one mapped entity in JpaRepository 【发布时间】:2020-01-15 22:10:37 【问题描述】:我有两个实体并使用多对一注释映射了这些实体,但是在使用另一个表 id 编写查找对象的查询后,当我注释掉该应用程序调用的行和方法时出现错误,但我想实现该功能,请帮助我
这些是我的实体类:
@Entity
@Table(name = "Contract")
public class Contract implements Serializable
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "contractId")
private long contractId;
@Column(name="start_date")
private Date st_date;
@Column(name="end_date")
private Date end_date;
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "hotel_id", nullable = false)
@OnDelete(action = OnDeleteAction.CASCADE)
@JsonIgnore
private Hotel hotel;
// getters and setters
第二个实体
@Entity
@Table(name="Hotel")
public class Hotel
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="hotel_id")
private long hotel_id;
@Column(name="hotel_name")
private String hotel_name;
@Column(name="hotel_location")
private String hotel_location;
@Column(name="hotel_email")
private String hotel_email;
@Column(name="hotel_telephone")
private String hotel_telephone
// getters and setters
我的合同服务类
@Service
public class ContractService
@Autowired
private ContractRepository contractRepository;
@Autowired
private HotelRepository hotelRepository;
public List<Contract> getAllContracts()
return contractRepository.findAll();
public List<Contract> findByHotelId(Long hotelId,Pageable pageable)
return contractRepository.findByHotelId(hotelId, pageable);
public ResponseEntity<?> deleteContract(Long hotelId, Long contractId)
return contractRepository.findByIdAndHotelId(contractId,
hotelId).map(Contract ->
contractRepository.delete(Contract);
return ResponseEntity.ok().build();
).orElseThrow(() -> new ResourceNotFoundException("Comment not found
with ContractId " + contractId + " and hotelId " + hotelId));
我的合约仓库
@Repository
public interface ContractRepository extends JpaRepository<Contract, Long>
List<Contract> findByHotelId(Long hotelId, Pageable pageable);
Optional<Contract> findByIdAndHotelId(Long id, Long hotelId);
我在运行我的项目时遇到了这个错误
org.springframework.beans.factory.UnsatisfiedDependencyException: 创建名为“contractController”的 bean 时出错:通过字段“contractService”表示的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.UnsatisfiedDependencyException:创建名称为“contractService”的 bean 时出错:通过字段“contractRepository”表示的依赖关系不满足;嵌套异常是 org.springframework.beans.factory.BeanCreationException:创建名为“contractRepository”的 bean 时出错:调用 init 方法失败;嵌套异常是 java.lang.IllegalArgumentException: 无法为方法 public abstract java.util.List com.sunTravel.sunRest.repository.ContractRepository.findByHotelId(java.lang.Long,org.springframework.data.domain.Pageable) 创建查询!未找到类型酒店的属性 ID!遍历路径:Contract.hotel。
【问题讨论】:
【参考方案1】:第一个解决方案:根据您的堆栈跟踪,Spring 数据正在您的 Hotel
类中查找 id 变量(主键)。所以请将private long hotel_id;
改为private long id;
另一种解决方案(无需更改任何内容,只需添加您自己的查询):
使用 @Query
编写您自己的 JPA 查询。
例子:
@Query("SELECT contract from Contract as contract where contract.hotel.hotel_id = :hotelId")
List<Contract> findByHotelId(Long hotelId, Pageable pageable);
【讨论】:
【参考方案2】:您应该将主键从 hotel_id 重命名为 id,然后只有您的存储库方法才能工作。
@Entity
@Table(name="Hotel")
public class Hotel
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="hotel_id")
private long id;
@Column(name="hotel_name")
private String hotel_name;
@Column(name="hotel_location")
private String hotel_location;
@Column(name="hotel_email")
private String hotel_email;
@Column(name="hotel_telephone")
private String hotel_telephone
// getters and setters
【讨论】:
以上是关于如何在 JpaRepository 中为多对一映射实体编写查询的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Rails 4 中为多对多关联制作带有子表单的表单?
如何在 Django REST 框架中为多对多字段定义“IsOwner”自定义权限?