我们有一个名为Location的项目,并且已经成功实现了jparepositories,定义了几种搜索方法。我们希望有一个额外的搜索方法可以返回一组街道名称(从位置表中提取)而不是一组位置 - 因此我们可以在用户在街道中键入时实现自动完成。首先我们尝试了@Query注释:
@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);
}
如果我查询了一条不存在的街道的程序(例如,没有以X开头的街道),我会返回一个空集{}。如果我查询确实存在的街道(街道= Br,因为百老汇存在于数据库中),我得到了
{"cause":null,"message":"PersistentEntity must not be null!"}
然后我们尝试使用以下方法将其实现为自定义查询:
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;
}
}
这也给了我们&#34; PersistentEntity不能为空&#34;错误。实现中的代码用于返回硬代码结果,因此我们没有试图弄清楚我们的SQL是错还是我们的架构。我们在调试下运行它并验证确实返回了两个项目的列表。
问题似乎是从存储库返回除List之外的任何内容。这是对这种架构的限制吗?或者我们做错了什么,如果我们学会秘密握手,一切都会变得笨拙?
答案 0 :(得分:0)
我错过的线索是'PersistentEntity不能为空'。存储库框架想要返回已注册实体的列表 - 而不是任何旧的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> {
}
然后,我在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;
}
现在返回StreetNames列表。 (它们被格式化为字符串项的hrefs,因此所有空格都替换为%20,但我可以处理它。)有趣的是注意到PString表不需要存在于数据库模式中 - 返回的hrefs实际上不会引用到数据库中的实际数据项。
请注意,这并没有回答如何使用@Query注释执行此操作的问题。我通过返回List再次尝试了,但仍然遇到了同样的错误。