Spring Data JPA @Query - select max

3
我正在尝试使用select max&where@Query编写查询语句。 下面的代码不起作用,我该如何解决?
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

@Repository
interface IntermediateInvoiceRepository extends JpaRepository<Invoice, String> {

@Query("SELECT max(i.sequence) " +
        "FROM Invoice as i " +
        "WHERE i.fleetId = :fleetId" +
        "   AND i.sequence IS NOT NULL")
Long findMaxSequence(@Param("fleetId") String fleetId);

}

我遇到了另一个答案,但它明确使用实体管理器,所以不同。

如何在JPA 2.0中编写带有where子句的MAX查询?

错误是:

2018-09-14T09:27:57,180Z  [main] ERROR o.s.boot.SpringApplication     - Application startup failed
org.springframework.data.mapping.PropertyReferenceException: No property findMaxSequence found for type Invoice!

发票类(为简洁起见进行了简化):

@Entity
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Table(name = "invoices", indexes = {
        @Index(name = "IDX_FLEET", columnList = "fleetId", unique = false)
        ,
        @Index(name = "IDX_USERSSS", columnList = "userId", unique = false)
        ,
        @Index(name = "IDX_TIME", columnList = "invoiceDate", unique = false)
        ,
        @Index(name = "IDX_SEQUENCE", columnList = "sequence", unique = false)
})
@JsonIgnoreProperties(ignoreUnknown = true)
public class Invoice implements Serializable {

    private static final long serialVersionUID = 1L;

    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid2")
    @Column(columnDefinition = "CHAR(36)")
    @Id
    private String id;

    @Column
    private long sequence;

...

更新:

  • 或许可以使用findOne方法,按照序列列进行降序排序来解决问题?

    @Query("SELECT i.sequence " + "FROM Invoice as i " + "WHERE i.fleetId = :fleetId " + "ORDER BY i.sequence DESC ") Long getMaxSequence(@Param("fleetId") String fleetId);

但是我需要对结果集进行限制,只返回一个结果。

更新2:

已经修复了import org.springframework.data.jpa.repository.Query;,但还存在错误。


1
Spring Data非常传统,以find开头的方法名称可能会使其失效。当您将方法重命名为“getMaxSequence”时会发生什么? - Gimby
你可以尝试使用 NativeQuery 来检查是否出现相同的问题。 - Syed Anas
1
你能检查一下是否使用了 org.springframework.data.jpa.repository.Query 注解而不是其他注解吗? - eltabo
那看起来很不对劲。 - Gimby
1
@Query("select max(i.sequence) ...") 是正确的,也许你会遇到其他错误,但不是关于这个的。这个单元测试代码(repository.getMaxCode)可以证明它。除此之外,@Repository注解是不必要的,应该被移除。 - RJ.Hwang
显示剩余4条评论
2个回答

5

由于您正在使用JPA存储库,请使用:

org.springframework.data.jpa.repository.Query

使用注释替代

org.springframework.data.mongodb.repository.Query

你可以创建一个查询方法,不使用@Query注释,例如:
Invoice findFirstByFleetIdOrderBySequenceDesc(String fleetId);
它会返回你需要的发票。

0

我已经找到了一个解决方法:

创建一个简单的存储库方法,返回Page并接受一个Pageable

Page<Invoice> findByFleetId(String fleetId, Pageable pageable);

通过以下方式,我们可以模拟ORDER BY sequence LIMIT 1

long maxNewSeq = 0;
PageRequest pageRequest = new PageRequest(0, 1, Sort.Direction.DESC, "sequence");
Page<Invoice> pageableInvoices = invoiceRepository.findByFleetId(invoice.getFleetId(), pageRequest);
if(pageableInvoices.getTotalElements() > 0){
    maxNewSeq = pageableInvoices.getContent().get(0).getSequence();
}

invoice.setSequence(Math.max(0, maxNewSeq) + 1);

似乎像魔法一般正常运作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接