Spring数据JPA查询意外行为

时间:2015-01-09 06:18:50

标签: java spring-data-jpa

我有这些实体:

public class Order_status_sas {
   private Order_sas order;
   private Date lastModified;
   ...
}

public class Order_sas {
   private long id;
   ...
}

我的CrudRepository:

public interface StatusesWareHouseRepository extends CrudRepository<Order_status_sas, Long> {
   Order_status_sas findFirstByOrderIdOrderByLastModifiedDesc(long id);
}

我希望方法findFirstByOrderIdOrderByLastModifiedDesc将从表Order_status_sas返回第一行,其中order.id = <some_id>按字段lastModified排序,但在日志中我看到此查询:

Hibernate: select ... 
       from order_status_sas a 
          left outer join orders_sas b 
            on a.order_id=b.id 
       where b.id=? 
       order by a.last_modified desc

此查询不会返回一行,但返回行列表。似乎Spring Data不会在我的方法名称中查看单词First。另外,我得到一个例外:

org.springframework.dao.IncorrectResultSizeDataAccessException: 
result returns more than one elements; nested exception is javax.persistence.NonUniqueResultException: result returns more than one elements

请告诉我我做错了什么,我怎样才能达到目的?

编辑: 我使用自定义查询编辑了StatusesWareHouseRepository

@Query("select s from Order_status_sas s where s.order.id = ?1 order by s.lastModified desc limit 1")
Order_status_sas findFirstByOrderIdOrderByLastModifiedDesc(long id);

但是由Hibernate执行的查询没有改变。它看起来像这样:

select ... 
from order_status_sas s 
where s.order_id=? 
order by s.last_modified desc

2 个答案:

答案 0 :(得分:2)

好的,我理解@PriduNeemre点。让我们离开数据库模型,回到JPA问题。这是另一个例子:

@Entity
public class Client {
   ....
}

public interface ClientRepository extends CrudRepository<Client, Integer> {

Client findFirstByOrderByNameDesc();
}

Hibernate查询仍然如下所示:

select ... 
from clients c 
order by c.name desc

答案 1 :(得分:0)

您是否尝试在@Query方法之上添加findFirstByOrderIdOrderByLastModifiedDesc(..)注释(请参阅here)以手动指定预期行为?关于它如何工作的(非相关)示例:

public interface InvoiceRepository extends JpaRepository<Invoice, Long> {

    @Query("SELECT I FROM Invoice I JOIN I.customer C JOIN C.user U WHERE 
        U.username = :username")
    public List<Invoice> findInvoicesByUsername(@Param("username")
        String username);
}

请注意,注释正文中使用的查询语言实际上是JPQL,而不是SQL。有关@Query注释的更多示例,请参阅Spring Data文档here

PS:我对你的域对象结构感到矛盾, Order_sas的实例是否真的应该存储在Order_status_sas的实例中 - 应该是反过来呢?通常,您希望将引用对象存储在主域对象中,而不是反之亦然。 (虽然我有点不可能做到这一点。

编辑:我甚至会说,考虑到你当前的域模型,Hibernate正在做正确的事情,除了缺少一个LIMIT 1子句来将预期的结果集限制为一行。但是,查询本身效率极低,可以通过修复偏斜的域模型来改进。

相关问题