数据存储库自定义带注释的查询

时间:2015-11-10 15:47:27

标签: spring jpa spring-data-rest

我正在努力完成Spring Data-Rest指南并努力编写自定义带注释的查询,并且不确定它是否可能,这里是代码:

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)

}

上面的查询是我挣扎的问题,不知道如何正确地执行此操作。我搜索了几个小时寻找解决方案但找不到一个。

类别实体

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

}

广告资源实体

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
}

InventoryDe​​tail

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错误,我确定我忽略了一些东西,但不确定它是什么。

我提前感谢您的帮助!

修改

以下是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 ?

3 个答案:

答案 0 :(得分:1)

经过无数小时的测试后,我决定将代码放入控制器并通过EntityManager访问它,并且它有效。从控制器开始工作后,我意识到JPA / Hibernate期望实体而不是Object / DTO。

我能够做到这一点......

function isItAVowel(letter) {
    var vowel = ["a", "e", "i", "o", "u"];
    var text = vowel.indexOf(letter) != -1 ? "vowel" : "not vowel";
    document.getElementById("paragraph").innerHTML = text;
}

isItAVowel("i");

答案 1 :(得分: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+'%')")

在自定义查询中,没有类别和库存的连接映射。按照其在连接中的ID映射的类别和库存的位置来重新编码这行代码:

 @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

答案 2 :(得分:0)

我不确定这是否是导致500错误的原因,但我发现您的查询有问题,尤其是您如何将参数name与通配符%连接起来。< / p>

@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