Spring 启动 JPA 如何在 @Transient 属性上查询过滤器
Spring boot JPA how to query filter on @Transient attribute
我正在使用 spring boot 1.3.3 with starter-data-jpa + 我正在使用 specification-arg-resolver 在 JPA Repo
中组合多个过滤器
我在实体中有一个与数据库状态 ID 匹配的已归档调用状态属性,但是,我们想按状态名称搜索,我在实体的 hashMap 中定义了所有状态名称,如下代码
然而,当我尝试按状态名称过滤时,我得到了
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.Inscription]
上找到具有给定名称 [statusName] 的属性
实体 class:
@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);
}
}
控制器Class:
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;
}
回购 Class:
public interface InscriptionRepository extends PagingAndSortingRepository<Inscription, String>, JpaSpecificationExecutor<Inscription> { }
@Transient
注解用于表示一个字段不被持久化到数据库中,也就是说它在数据库中没有对应的,你不能查询它。
并且由于 statutName
与 status
相关,后者不是瞬态的,您可以使用 status
代替。
感谢@Rafik BELDI 我按照规范做了它,希望这可以帮助任何遇到同样问题的人。
规格class
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));
};
}
}
控制器class
@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;
}
}
我正在使用 spring boot 1.3.3 with starter-data-jpa + 我正在使用 specification-arg-resolver 在 JPA Repo
中组合多个过滤器我在实体中有一个与数据库状态 ID 匹配的已归档调用状态属性,但是,我们想按状态名称搜索,我在实体的 hashMap 中定义了所有状态名称,如下代码
然而,当我尝试按状态名称过滤时,我得到了
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.Inscription]
上找到具有给定名称 [statusName] 的属性实体 class:
@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);
}
}
控制器Class:
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;
}
回购 Class:
public interface InscriptionRepository extends PagingAndSortingRepository<Inscription, String>, JpaSpecificationExecutor<Inscription> { }
@Transient
注解用于表示一个字段不被持久化到数据库中,也就是说它在数据库中没有对应的,你不能查询它。
并且由于 statutName
与 status
相关,后者不是瞬态的,您可以使用 status
代替。
感谢@Rafik BELDI 我按照规范做了它,希望这可以帮助任何遇到同样问题的人。
规格class
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));
};
}
}
控制器class
@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;
}
}