我可以将enum参数用于JpaRepository nativeQuery吗?

时间:2017-06-09 14:28:55

标签: java sql hibernate enums spring-data-jpa

实体看起来像这样:

@Getter
@Setter
@Entity
public class Application {
@Id
private Long id;
@Enumerated(EnumType.STRING)
private ApplicationStatus status;
}

代码以这种方式工作:

public interface ApplicationRepository extends JpaRepository<Application, Long> {
@Query("SELECT app FROM #{#entityName} AS app WHERE app.status LIKE :status")
List<Application> find(@Param("status") ApplicationStatus status);

但是使用nativeQuery的相同代码段 - 不会:

@Query(value = "SELECT app.* FROM application AS app WHERE app.status LIKE :status", nativeQuery = true)
List<Application> findNative(@Param("status") ApplicationStatus status);
}

我没有任何例外,只是空列表。

我该如何解决这个问题?是否可以将enumnativeQuery一起使用?

P.S我可以将String传递给方法而不是ApplicationStatus,但也许还有其他选项?

6 个答案:

答案 0 :(得分:4)

similar question的要求类似并且one of the answers指向Spring Expression Language (SpEL)之后,您可以使用:

$tzOffset = '-0100'; // Getting from request

if (substr($tzOffset, 0, 1) === '+') {
    $tzOffset = str_replace('+', '-', $tzOffset);
} else {
    $tzOffset = str_replace('-', '+', $tzOffset);
}

$timezone = new DateTimeZone($tzOffset);

// rest ...

重要的部分是public interface ApplicationRepository extends JpaRepository<Application, Long> { @Query(nativeQuery = true, value = "SELECT app FROM #{#entityName} AS app WHERE app.status=:#{#status.name()}") List<Application> find(@Param("status") ApplicationStatus status); }

答案 1 :(得分:0)

怎么样?

public interface ApplicationRepository extends JpaRepository<Application, Long> {
List<Application> findByStatus(ApplicationStatus status);

答案 2 :(得分:0)

你可以在传递参数之前转换为字符串。

答案 3 :(得分:0)

扩展@Aivaras答案: 如果您要使用状态列表,则SpEL的展示效果略有不同-您需要进行投影:

public interface ApplicationRepository extends JpaRepository<Application, Long> {
    @Query(nativeQuery = true, value = "SELECT app FROM #{#entityName} AS app WHERE app.status in :#{#statuses.![name()]}")
    List<Application> find(@Param("statuses") List<ApplicationStatus> statuses);
}

请注意将表达式更改为

#{#statuses.![name()]}

答案 4 :(得分:0)

出现此错误几天后,我找到了解决方案。

我进行了大量研究并以多种方式测试了作为参数接收 @Param("environment") environment: Environment

 :#{#environment.TESTING}
 :#{#environment}
 :#{#environment.name()}
 CAST(:#{#environment.name()} as environment)

Kotlin 中的解决方案

键在查询中。 您必须使用 .name() 将参数的值转换为字符串(或接收字符串作为参数)并将该字符串类型的值转换为所需的特定枚举。因为在查询中直接传递 Enum 类型的对象不起作用。

假设您数据库中的 Enum 定义为 environment

@Query(
        value = "SELECT some_routine(CAST(:#{#environmentNamedParam.name()} as environment))",
        nativeQuery = true
)
fun yourFunction(
        @Param("environmentNamedParam") environmentParam: Environment
) : Boolean

区分:

  • environmentNamedParam
  • 环境参数
  • 环境

#spring #jpa #postgresql #kotlin

答案 5 :(得分:0)

我使用 #{#paramName?.name()}

解决了这个问题
public interface ItemRepository extends JpaRepository<Item, Long> {
    @Query(value = "select * from items where type = :#{#type?.name()}", nativeQuery = true)
    List<Item> findByType(@Param("type") EnumType type);
}
 
public enum EnumType { NORMAL, LARGE };