Java Spring boot JPA如何查询@Transient属性上的过滤器
我正在使用SpringBoot 1.3.3和starter数据jpa+在jpa Repo中组合多个过滤器 我在实体中有一个Field call status属性,它与数据库状态id相匹配,然而,我们希望按状态名称进行搜索,我在实体的hashMap中定义了所有状态名称,如下代码所示 但是,当我尝试按状态名称筛选时,我得到了Java Spring boot JPA如何查询@Transient属性上的过滤器,java,hibernate,spring-boot,spring-data,spring-data-jpa,Java,Hibernate,Spring Boot,Spring Data,Spring Data Jpa,我正在使用SpringBoot 1.3.3和starter数据jpa+在jpa Repo中组合多个过滤器 我在实体中有一个Field call status属性,它与数据库状态id相匹配,然而,我们希望按状态名称进行搜索,我在实体的hashMap中定义了所有状态名称,如下代码所示 但是,当我尝试按状态名称筛选时,我得到了 Servlet.service() for servlet [dispatcherServlet] in context with path [] threw excepti
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Unable to locate Attribute with the the given name [statusName] on this ManagedType [api.domain.Inscription]; nested exception is java.lang.IllegalArgumentException: Unable to locate Attribute with the the given name [statusName] on this ManagedType [api.domain.Inscription]] with root cause
java.lang.IllegalArgumentException:无法在此ManagedType[api.domain.Deltination]上找到具有给定名称[statusName]的属性
实体类:
控制器类:
回购类别:
@瞬态注释用于指示某个字段不在数据库中持久化,这意味着该字段在数据库中没有等价项,您无法对其进行查询
由于StateTName与状态相关,而不是transiet,因此您可以使用status来代替它。感谢@Rafik BELDI,我用规范完成了它,希望这可以帮助任何有同样问题的人 等级规范 控制器类
为什么在不需要的时候将@Transient放在它上面?@mh dev因为statusName不在表中,status是exist,但它是status的id,我想按status名称进行筛选。但是正如我在问题statusName不在数据库中所解释的,status不在数据库中。然而,状态是数据库中的id。我希望他们传递字符串ex.rent而不是id。我怎么做?@zt1983811您不能将字符串传递到数据库,它没有任何意义,将其转换为状态并查询状态这是您唯一的方法it@zt1983811无论您使用什么方法,最终都会查询状态。我使用querydsl和规范,您所能做的就是传递statusName并从STATUS中检索其等效项,然后通过STATUS查询db。是@Rafik BELDI这就是我要做的,您是建议更多规范还是查询DSL?@zt1983811如果您不通过classe主键,请保持我的更新:
@Entity
@Table(name="INSCRIPTIONS")
public class Inscription {
private static final Map<Byte, String> STATUS = new HashMap<Byte, String>(){{
put((byte) 1, "sale");
put((byte) 3, "rent");
}};
private byte status;
@Transient
private String statusName;
public byte getStatus() {
return this.status;
}
public void setStatus(byte status) {
this.status = status;
}
public String getStatusName() {
return STATUS.get(this.status);
}
public void setStatusName(byte status) {
this.statusName = STATUS.get(status);
}
}
public class InscriptionController
{
@Autowired
private InscriptionRepository inscriptionRepository;
@RequestMapping(method = RequestMethod.GET)
public Page<Inscription> findAll(
final @RequestParam(defaultValue = "0", required = false) int offset,
final @RequestParam(defaultValue = "20", required = false) int limit,
@Spec(params = "status", path = "statusName", spec = In.class) Specification<Inscription> spec
)
{
Page<Inscription> inscriptions = inscriptionRepository.findAll(spec, new PageRequest(offset, limit));
return inscriptions;
}
public interface InscriptionRepository extends PagingAndSortingRepository<Inscription, String>, JpaSpecificationExecutor<Inscription> { }
public class InscriptionSpecification
{
public static Specification<Inscription> statusNameIn(String[] statusNames) {
if (statusNames == null || statusNames.length == 0) {
return null;
}
return (root, query, cb) -> {
Inscription inscription = new Inscription();
List<Byte> statusIds = new ArrayList<Byte>();
for (String oneStatusName : statusNames) {
statusIds.add(inscription.getStatusIdByName(oneStatusName));
}
return cb.isTrue(root.<String>get("status").in(statusIds));
};
}
}
@RequestMapping(method = RequestMethod.GET)
public Page<Inscription> findAll(
final @RequestParam(defaultValue = "0", required = false) int offset,
final @RequestParam(defaultValue = "20", required = false) int limit,
final @RequestParam(required = false) String[] status
)
{
Specification<Inscription> specStatusNameIn = InscriptionSpecification.statusNameIn(status);
inscriptionRepository.findAll(specStatusNameIn, new PageRequest(offset, limit));
return inscriptions;
}
}