2015-11-10 2 views
1

Я работаю свой путь через Spring Data-Rest руководство и пытаюсь писать пользовательский аннотированный запрос и не уверен, если это вообще возможно, вот код:данные Rest Repository Пользовательских Annotated Query

CategoryRepository

package com.example.repositories 

import org.springframework.data.domain.Page 
import org.springframework.data.domain.Pageable 
import org.springframework.data.jpa.repository.JpaRepository 
import org.springframework.data.jpa.repository.Query 
import org.springframework.data.repository.query.Param 
import org.springframework.data.rest.core.annotation.RepositoryRestResource 
import org.springframework.data.rest.core.annotation.RestResource 

import com.example.entities.Category 
import com.example.entities.InventoryDetail 

@RepositoryRestResource(collectionResourceRel="categories", path="categories") 
interface CategoryRepository extends JpaRepository<Category, Long> { 

    @RestResource(path="inventoryByCategory",rel="inventoryByCategory") 
    @Query("select new com.example.entities.InventoryDetail(i.id, i.item, c.name) from Category c join c.inventory i where upper(c.name) like upper(:name+'%')") 
    Page<InventoryDetail> queryByCategoryStartsWithIgnoreCase(@Param("name") String name, Pageable pageable) 

} 

Вышеупомянутый запрос - это тот, с которым я борюсь, не знаю, как правильно это сделать. Я искал часы для поиска решения, но не смог найти его.

Категория Entity

package com.example.entities 

import javax.persistence.Column 
import javax.persistence.Entity 
import javax.persistence.FetchType 
import javax.persistence.GeneratedValue 
import javax.persistence.GenerationType 
import javax.persistence.Id 
import javax.persistence.JoinColumn 
import javax.persistence.OneToMany 
import javax.persistence.Table 

@Entity 
@Table(name="categories") 
class Category implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    long id 

    @Column 
    String name 

    @Column 
    String description 

    @OneToMany(targetEntity=Inventory.class, fetch=FetchType.LAZY) 
    @JoinColumn(name="category") 
    List<Inventory> inventory 

} 

Инвентарь Entity

package com.example.entities 

import javax.persistence.Column 
import javax.persistence.Entity 
import javax.persistence.GeneratedValue 
import javax.persistence.GenerationType 
import javax.persistence.Id 
import javax.persistence.Index 
import javax.persistence.Table 

@Entity 
@Table(name="inventory", indexes=[ @Index(columnList="category", unique=false) ]) 
class Inventory implements Serializable { 

    private static final long serialVersionUID = 1L; 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    long id 

    @Column 
    long category 

    @Column 
    String item 

    @Column 
    String description 

    @Column 
    long price 

    @Column 
    long onHand 
} 

InventoryDetail

package com.example.entities 

import javax.persistence.Column; 

class InventoryDetail { 

    long id 

    String item 

    String name 

    InventoryDetail(long id, String item, String name) { 
     this.id = id 
     this.item = item 
     this.name = name 
    } 

} 

Если я хочу выбрать определенные поля из обоих объектов, нужно ли иметь настраиваемый DTO, как тот, который указан выше? Возможно ли использовать вместо этого new map(...)? В любом случае запрос выполняется, и я вижу его в консоли, но в браузере HAL это дает мне ошибку 500, я уверен, что я что-то пропускаю, но не уверен, что это такое.

Я ценю вашу помощь заранее!

EDIT

Вот выход из запроса Hibernate:

Hibernate: select count(category0_.id) as col_0_0_ from categories category0_ inner join inventory inventory1_ on category0_.id=inventory1_.category where upper(category0_.name) like upper(?+'%') 
Hibernate: select inventory1_.id as col_0_0_, inventory1_.item as col_1_0_, category0_.name as col_2_0_ from categories category0_ inner join inventory inventory1_ on category0_.id=inventory1_.category where upper(category0_.name) like upper(?+'%') limit ? 
+0

Внутреннее соединение позволяет выбирать только общие данные из категорий и инвентаря. Используйте левое соединение, если вам нужны категории, основанные на инвентаре или подходящие, если вам нужны категории на основе инвентаря. – developerbhuwan

+0

Я пробовал оба, влево и вправо, и никто не работал на меня. –

+0

Любое исключение? – developerbhuwan

ответ

1

После бесчисленных часов испытаний, я решил бросить код в контроллере и получить доступ к нему через EntityManager, и он сработал. Получив его от контроллера, я понял, что JPA/Hibernate ожидает Entity, а не Object/DTO.

я был в состоянии сделать это ...

List<Object> list(String name) { 
    def qry = "select new map(i.id as id, i.item as item, c.name as category) from Category c join c.inventory i where upper(c.name) like upper(:name+'%')" 
    List<Object> results = em.createQuery(qry).setParameter('name',name).getResultList() 
    return results 
} 
0

Ваш запрос:

@Query("select new com.example.entities.InventoryDetail(i.id, i.item, c.name) from Category c join c.inventory i where upper(c.name) like upper(:name+'%')") 

В пользовательском запросе не присоединиться отображение для категории и инвентаризации. Repace эта строка кода, следуя которой Категория и инвентаризации отображается их идентификатору в присоединиться:

@Query("select new com.example.entities.InventoryDetail(i.id, i.item, c.name) from Category c join c.inventory i where c.id=i.category upper(c.name) like upper(:name+'%')") 

Примечание: по умолчанию jpql join означает inner join

+0

Отображение соединения автоматически появляется, если вы посмотрите на запрос спящего режима, который я вставил в свой вопрос. Определив, что в сущности я не должен был определять его в запросе. Это не сработало, я попробовал. –

+0

Пожалуйста, добавьте модификатор доступа 'public' в класс' Category', 'Inventory',' InventoryDetail', затем проверьте его. – developerbhuwan

0

Я не уверен, если это является причиной вашей ошибки 500, но я вижу что-то не так с вашим запросом, в частности, с тем, как вы сростить paramater name с символом подстановки %.

@Query("select new com.example.entities.InventoryDetail(i.id, i.item, c.name) from Category c join c.inventory i where upper(c.name) like upper(:name+'%')") 

Вы должны удалить знак плюс и одинарные кавычки.

@Query("select new com.example.entities.InventoryDetail(i.id, i.item, c.name) from Category c join c.inventory i where upper(c.name) like upper(:name%)") 

См. Пример внедрения here.

+0

Я использую Groovy для большей части проекта, я не получил от этого ошибки. Ошибка была вызвана тем, что я не возвращал «Entity», что ожидает JPA/Hibernate. –

Смежные вопросы