Как се създава персонализирана заявка в jparepository, но се връща обект, различен от обекта?

Имаме проект с клас, наречен 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, например), получих празен набор {} върнат. Ако потърся улица, която наистина съществува (street=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;
   }
 }

Това също ни дава грешката „PersistentEntity не трябва да е нула“. Кодът в изпълнението беше използван за връщане на резултат от твърд код, така че не се опитвахме да разберем дали нашият SQL е грешен или нашата архитектура. Пуснахме го при отстраняване на грешки и проверихме, че наистина списъкът с два елемента е върнат.

Изглежда, че проблемът връща нещо различно от списък от хранилището. Това ограничение ли е за тази архитектура? или има нещо, което правим грешно и че ако научим тайното ръкостискане, всичко ще бъде ужасно?


person LitterWalker    schedule 15.01.2015    source източник


Отговори (1)


Уликата, която бях пропуснал, беше „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; 
}

Това вече връща списък с имена на улици. (Те са форматирани като hrefs за низови елементи, като по този начин всички интервали се заменят с %20, но мога да се справя с това.) Интересно е да се отбележи, че таблицата PString не е необходимо да съществува в схемата на базата данни - върнатите href всъщност не препращат към действителни елементи от данни в базата данни.

Имайте предвид, че това не дава отговор на въпроса как да го направите с анотацията @Query. Опитах това отново, като върнах List, но пак получих същата грешка.

person LitterWalker    schedule 16.01.2015
comment
Този подход не работи добре за мен, намерихте ли решение? ако да, можете ли да отговорите тук:stackoverflow.com/questions/33538426/ - person Dipanshu Verma; 05.11.2015