Rest 如何在jparepository中创建自定义查询,但返回实体以外的对象?
我们有一个名为Location的类的项目,并且成功地实现了jparepositories,定义了几个搜索方法。我们希望有一个额外的搜索方法,它将返回一组街道名称(从位置表中提取),而不是一组位置-因此我们可以在用户在街道中键入时实现自动完成。首先,我们尝试了@Query注释:Rest 如何在jparepository中创建自定义查询,但返回实体以外的对象?,rest,repository,spring-data-jpa,Rest,Repository,Spring Data Jpa,我们有一个名为Location的类的项目,并且成功地实现了jparepositories,定义了几个搜索方法。我们希望有一个额外的搜索方法,它将返回一组街道名称(从位置表中提取),而不是一组位置-因此我们可以在用户在街道中键入时实现自动完成。首先,我们尝试了@Query注释: @RepositoryRestResource(collectionResourceRel = "locations", path = "locations") public interface LocationRep
@RepositoryRestResource(collectionResourceRel = "locations", path = "locations")
public interface LocationRepository extends JpaRepository<Location, Integer>, LocationRepositoryCustom {
List<Location> findByStreetNameStartingWithIgnoreCase(@Param("street") String streetName);
@Modifying
@Query("select x.streetName from Location x where x.streetName like :street%")
List<String> findStreetNameStartingWith(@Param("street") String streetName);
}
然后,我们尝试将其实现为自定义查询,使用:
public interface LocationRepositoryCustom {
@Query("select x.streetName from Location x where x.streetName like :streetName")
public List<String> collectStreetNames(@Param("streetName") String streetName);
}
class LocationRepositoryImpl implements LocationRepositoryCustom {
@PersistenceContext
private EntityManager em;
@Override
public List<String> collectStreetNames(String streetName) {
List<String> retList = new ArrayList<String>();
retList.add("start");
retList.add("end");
return retList;
}
}
公共接口位置RepositoryCustom{
@查询(“从位置x选择x.streetName,其中x.streetName类似:streetName”)
公共列表集合streetName(@Param(“streetName”)字符串streetName);
}
类LocationRepositoryImpl实现LocationRepositoryCustom{
@持久上下文
私人实体管理者;
@凌驾
公共列表集合streetName(字符串streetName){
List retList=new ArrayList();
添加(“开始”);
重新列出。添加(“结束”);
返回列表;
}
}
这也给了我们“PersistentEntity不得为null”错误。实现中的代码用于返回硬代码结果,因此我们没有试图找出我们的SQL是错误的还是我们的体系结构是错误的。我们在debug下运行它,并验证是否返回了两个项目的列表
问题似乎是从存储库返回列表以外的任何内容。这是对这种架构的限制吗?还是说我们做错了什么,如果我们学会了秘密握手,一切都会好起来?我错过的线索是“持久性不能为空”。存储库框架希望返回已注册实体的列表,而不是任何旧的POJO或原语。解决方案是定义查询可以返回的实体:
@Entity
@Table(name="PString")
public class PString {
@Column(name="Name", length=40)
@Id
private String value;
public PString() { }
public PString(String name) {
this.value = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
除此之外,还需要一个标准的PStringRepository:
@RepositoryRestResource(collectionResourceRel = "strings", path = "strings")
public interface PStringRepository extends JpaRepository<PString, String> {
}
@RepositoryRestResource(collectionResourceRel=“strings”,path=“strings”)
公共接口PStringRepository扩展了JpaRepository{
}
然后,LocationRepositoryCustom中的自定义函数变为:
@Override
public List<PString> collectStreetNames(String streetName)
{
Query query = em.createNativeQuery("select distinct streetName from Location where streetName like ?");
query.setParameter(1, streetName + "%");
List<PString> returned = new ArrayList<PString>();
@SuppressWarnings("unchecked")
List<String> list = query.getResultList();
for (String string : list)
{
returned.add(new PString(string));
}
return returned;
}
@覆盖
公共列表集合streetName(字符串streetName)
{
Query Query=em.createNativeQuery(“从streetName类似的位置选择不同的streetName?”);
query.setParameter(1,streetName+“%”);
返回的列表=新的ArrayList();
@抑制警告(“未选中”)
List=query.getResultList();
用于(字符串:列表)
{
返回.add(新的PString(字符串));
}
返回;
}
现在返回街道名称列表。(它们被格式化为字符串项的HREF,因此所有空格都替换为%20,但我可以处理它。)有趣的是,PString表不需要存在于数据库架构中-返回的HREF实际上并不引用数据库中的实际数据项
请注意,这并没有回答如何使用@Query注释执行此操作的问题。我再次尝试返回列表,但仍然出现相同的错误。这种方法对我来说不太有效,您找到解决方案了吗?如果是,您能在这里回答:
@Override
public List<PString> collectStreetNames(String streetName)
{
Query query = em.createNativeQuery("select distinct streetName from Location where streetName like ?");
query.setParameter(1, streetName + "%");
List<PString> returned = new ArrayList<PString>();
@SuppressWarnings("unchecked")
List<String> list = query.getResultList();
for (String string : list)
{
returned.add(new PString(string));
}
return returned;
}