具有可空Enum的Spring Data查询

时间:2014-09-10 07:58:23

标签: java hibernate jpa spring-data

我们有一个域类

@Entity
public class Gallery implements Serializable {

    @Id
    @GeneratedValue
    private Long id;

    @Enumerated(EnumType.ORDINAL)
    private Status status;

    // more attributes and getters/setters
}

状态为枚举:

public enum Status {

    OPEN (0, "offen"),
    ACTIVE (1, "aktiv"),
    INACTIVE (2, "inaktiv");

    // attributes, constructor...
}

然后我们有一个带有查询的Spring Data存储库:

public interface GalleryRepository extends PagingAndSortingRepository<Gallery, Long> {

    @Query("SELECT g FROM Gallery g WHERE (:status IS NULL or g.status = :status)")
    public List<Gallery> findBySearchCriteria(@Param("status") Status status);
}

(:status IS NULL or g.status = :status)的目的是,当没有给出状态时,我们需要所有数据,并在给出状态时仅获取适当的数据。

当状态为空时,我们会从此查询中获得结果,但如果状态为例如我们则不会得到任何结果ACTIVE,虽然数据库中有数据,状态= ACTIVE。

Wenn我们从查询中删除:status IS NULL or,当状态为ACTIVE时我们得到结果。查询看起来像

public interface GalleryRepository extends PagingAndSortingRepository<Gallery, Long> {

    @Query("SELECT g FROM Gallery g WHERE (g.status = :status)")
    public List<Gallery> findBySearchCriteria(@Param("status") Status status);
}

我记录了SQL和参数,当我手动运行SQL(带:status IS NULL or)时,我得到了预期的结果:

Hibernate: select gallery0_.id as id1_13_, gallery0_.institution_id as institut5_13_, gallery0_.internName as internNa2_13_, gallery0_.name as name3_13_, gallery0_.selectedShortId_id as selected6_13_, gallery0_.status as status4_13_ from Gallery gallery0_ where ? is null or gallery0_.status=?
2014-09-10 09:54:49,531 TRACE type.descriptor.sql.BasicBinder: binding parameter [1] as [VARBINARY] - ACTIVE
2014-09-10 09:54:49,531 TRACE type.descriptor.sql.BasicBinder: binding parameter [1] as [VARBINARY] - ACTIVE
2014-09-10 09:54:49,535 TRACE type.descriptor.sql.BasicBinder: binding parameter [2] as [VARBINARY] - ACTIVE
2014-09-10 09:54:49,535 TRACE type.descriptor.sql.BasicBinder: binding parameter [2] as [VARBINARY] - ACTIVE

SQL是

select gallery0_.id as id1_13_, gallery0_.institution_id as institut5_13_, gallery0_.internName as internNa2_13_, gallery0_.name as name3_13_, gallery0_.selectedShortId_id as selected6_13_, gallery0_.status as status4_13_ 
from Gallery gallery0_ 
where 1 is null or gallery0_.status=1

当我们使用其他数据类型(例如String)时,构造(例如(:name IS NULL or g.name = :name)的工作方式与预期的一样。

这个带枚举的构造有什么问题,或者是不是可以在Spring Data / JPA中做到这一点?

我们可能的解决方法是写入查询,一个有状态,一个没有。根据状态是否为null,我们将在存储库中调用适当的方法。

3 个答案:

答案 0 :(得分:2)

我在Spring数据查询中遇到了与Enum参数非常相似的问题,并设法通过在查询中使用字符串来解决它(保持实体映射与Enums一样):

public interface GalleryRepository extends PagingAndSortingRepository<Gallery, Long> {

@Query("SELECT g FROM Gallery g WHERE (:status IS NULL or g.status = :status)")
    public List<Gallery> findBySearchCriteria(@Param("status") String status);
}

答案 1 :(得分:0)

您是否尝试过使用方法名称创建查询?

public interface GalleryRepository extends JpaRepository<Gallery, Long> {
    public List<Gallery> findByStatus(Status status);
}

答案 2 :(得分:0)

您可以尝试

public interface GalleryRepository extends PagingAndSortingRepository<Gallery, Long> {
    @Query(value = "SELECT g FROM Gallery g WHERE (CAST(:status AS string) IS NULL OR g.status = :status)")
    List<Gallery> findBySearchCriteria(@Param("status") Status status);
}

此方法也适用于日期。