即使未定义 `setMaxResults`,JPA 也会限制 `queryResultLimit`

Posted

技术标签:

【中文标题】即使未定义 `setMaxResults`,JPA 也会限制 `queryResultLimit`【英文标题】:JPA limits `queryResultList` even though `setMaxResults` is not definied 【发布时间】:2019-07-03 09:10:35 【问题描述】:

我编写了以下代码 sn-p 以使用 hibernate 作为 JPA 提供程序从 zips 表中获取某些 zip 文件的记录。

    public List<ZipEntity> getZipEntityFromZipName(String zipName, String version, String createdBy,
                                                      String type) throws FileException 

        int numAttempts = 0;
        do 
            numAttempts++;
            EntityManager entityManager = getNewEntityManager();
            try 
                TypedQuery<ZipEntity> query = entityManager
                        .createNamedQuery(Constants.Database.Queries.GET_FROM_ZIP_NAME, ZipEntity.class)
                        .setParameter("zipName", zipName)
                        .setParameter("version", version)
                        .setParameter("createdBy", createdBy)
                        .setParameter("type", type);
                return query.getResultList();
             catch (PersistenceException e) 
                validatePersistenceException(e);
             finally 
                closeEntityManager(entityManager);
            
         while (numAttempts <= maxRetries);
        throw new FileException("Database connection failed.");

这里是相关的实体类

@NamedNativeQueries(
        @NamedNativeQuery(
                name = Constants.Database.Queries.GET_FROM_ZIP_NAME,
                query = Constants.Database.Queries.GET_FROM_ZIP_NAME_QUERY,
                resultClass = ZipEntity.class
        )
)
@Entity
@Table(name = "zips")
public class ZipEntity 

    @EmbeddedId
    private ZipKey ZipKey;

    public ZipEntity() 

    

    public ZipEntity(String zipName, String version, String createdBy, String file, String type,
                      String extension) 

        this.ZipKey = new ZipKey(zipName, version, createdBy, file, type, extension);
    


@Embeddable
public class ZipKey implements Serializable 

    static final long serialVersionUID = 1L;

    @Column(name = "zip_name")
    private String zipName;

    @Column(name = "version")
    private String version;

    @Column(name = "created_by")
    private String createdBy;

    @Column(name = "filepath")
    private String file;

    @Column(name = "type")
    private String type;

    @Column(name = "extension")
    private String extension;

 // Getter, setters and Constructor

Constant类中的查询如下,

public static final String GET_FROM_ZIP_NAME = "getFile";
public static final String GET_FROM_ZIP_NAME_QUERY = "SELECT * FROM zips WHERE zip_name = " +
                    ":zipName AND version = :version AND created_by = :createdBy AND type = :type";

尽管setMaxResults() 没有为上述查询定义事件,但从上述代码 sn-p 获得的结果仅限于 25 条记录,尽管在 DB 上执行的相同查询会产生 35 条记录。我在这里做错了什么?

【问题讨论】:

您可以启用 H2 控制台并共享生成的查询吗?我假设像“限制?”在您的查询结束时。 getResultList() 将获取所有记录,并且不会限制要选择的记录数。问题可能出在您的 where 条件中,例如它可能被忽略为空值或空值 @LahiruWijesekara 不,我最后检查了日志没有limit ? 要分离问题,我建议您检查数据库中的运行查询。在 oracle 中,您可以将其获取为“select * from v$sql”。为此,您应该有一个专用的测试数据库,它不运行并发查询。 【参考方案1】:

请调试您的解决方案并检查“zipName”、“version”、“createdBy”的值以及“type”参数,以验证它们是否是您的预期值。此查询具有由 AND 逻辑组合的条件,这些条件会影响您的结果。要获得 35 条记录,您的参数应使您的条件适用于所有 35 条记录。

您可以在 NamedNativeQuery 中限制如下记录,它一次为您提供 35 条记录。

 @NamedNativeQuery(
                name = Constants.Database.Queries.GET_FROM_ZIP_NAME,
                query = Constants.Database.Queries.GET_FROM_ZIP_NAME_QUERY,
                fetchSize = 35,
                resultClass = ZipEntity.class
        )

【讨论】:

以上是关于即使未定义 `setMaxResults`,JPA 也会限制 `queryResultLimit`的主要内容,如果未能解决你的问题,请参考以下文章

对 JPA 2 条件查询进行分页

我们如何使用 JPA 计算 LAST 页面?

JPA 查询对不在查询中的列抛出“未找到”错误

JPA分页查询怎么做

Springboot+JPA(Hibernate)+Oracle AbstractMethodError 未定义或继承 isValid(int) 的实现

Eclipse 中单独 JAR 中的 JPA @MappedSuperclass 导致验证错误“实体未定义主键属性”