问题描述
我有这些实体-项目
@Entity
@Table(name="Item")
public class Item
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Long id;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="item_set_id")
private ItemSet itemSet;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="category_id")
private Category category;
@Column(name="category_name")
private String categoryName;
// 5 other fields which aren't required for the query
}
和Category
-
@Entity
@Table(name="Category")
public class Category
{
@Id
@Column(name="id")
private Long id;
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="parent_id")
private Category parent_id;
@Column(name="name")
private String name;
}
我需要运行此SQL查询:
select id,category_id,category_name from Item where item_set_id = ?
我正在ItemRepository
中使用此[1],但性能不佳。它正在检索Item
和Category
中的所有字段(包括不需要的与Category
的联接)。
[1]
@Query("SELECT i FROM Item i WHERE item_set_id = ?1")
List<Item> findByItemSet(Long itemSetId);
我正在尝试使用命名查询和投影来提高性能,但似乎无处可寻。我一直遇到-Validation Failed for query for method public abstract java.util.List findByItemSet(Long)
。我试图创建一个DTO类和一个接口来做同样的事情,但仍然无法正常工作。
@Query("SELECT a.id,"
+ "a.category_name,a.category_id FROM Item a WHERE a.item_set_id = :itemSetId")
List<Item> findByItemSet(Long itemSetId);
关于如何解决此问题的任何想法/建议?
编辑:我正在使用springboot 2.0.4-RELEASE,java 8和MS-sql Server 2012。
解决方法
您在HQL查询中错误地使用了列名,而应该使用属性名。
您可以访问关联的属性,这就是JPA / Hibernate的优势。使用
@Query("SELECT a.id,a.categoryName,a.category.id FROM Item a WHERE a.itemSet.id = :itemSetId")
List<Tuple> findByItemSet(Long itemSetId);
如果需要实体对象,还可以使用以下内容
@Query("FROM Item a LEFT JOIN FETCH a.category WHERE a.itemSet.id = :itemSetId")
List<Item> findByItemSet(Long itemSetId);
如果要使用自定义DTO,请使用:
@Query("SELECT new com.dto.ItemDTO(a.id,a.category.id) FROM Item a WHERE a.itemSet.id = :itemSetId")
List<ItemDTO> findByItemSet(@Param("itemSetId") Long itemSetId);