我可以在 JpaRepository nativeQuery 中使用枚举参数吗?
Posted
技术标签:
【中文标题】我可以在 JpaRepository nativeQuery 中使用枚举参数吗?【英文标题】:Can I use enum parameter into JpaRepository nativeQuery? 【发布时间】:2017-11-11 15:00:17 【问题描述】:实体看起来像这样:
@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 相同的 sn-p - 没有:
@Query(value = "SELECT app.* FROM application AS app WHERE app.status LIKE :status", nativeQuery = true)
List<Application> findNative(@Param("status") ApplicationStatus status);
我没有任何例外,只是空列表。
我该如何解决这个问题? enum
可以和nativeQuery
一起使用吗?
P.S 我可以将 String
传递给方法而不是 ApplicationStatus
但也许还有其他选择?
【问题讨论】:
你有什么错误吗?用 nativeQuery 运行 sn-p 后,你得到了什么? Problems with making a query when using Enum in entity的可能重复 @the_bluescreen 我没有任何例外,只是空列表 在方法中使用String
类型的 status
参数而不是枚举 ApplicationStatus
对我来说是一个很好的解决方案。
将值作为字符串传递是一种解决方法,但最好知道是否有更好的解决方案。如果是 JPA 查询,它似乎可以按预期工作,但如果是本机查询,则返回空结果
【参考方案1】:
以下similar question 具有类似要求,one of the answers 指向Spring Expression Language (SpEL),您可以使用:
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);
上面重要的部分是app.status=:##status.name()
【讨论】:
【参考方案2】:要扩展@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()]
【讨论】:
如果你不介意,你能解释一下spEL如何用于收集的语法吗? @ArunGowda 它被称为集合投影docs.spring.io/spring-framework/docs/current/reference/html/…。所以我们从枚举集合中创建字符串集合【参考方案3】:您可以在传递参数之前转换为字符串。
【讨论】:
正如我在上面写的“附言我可以将字符串传递给方法而不是 ApplicationStatus 但也许还有其他选择?”【参考方案4】:在出现此错误几天后,我找到了解决方案。
我做了很多研究,并以多种方式测试了将@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】:我使用##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 ;
【讨论】:
【参考方案6】:这个怎么样?
public interface ApplicationRepository extends JpaRepository<Application, Long>
List<Application> findByStatus(ApplicationStatus status);
【讨论】:
在我的问题中,我使用了简化示例,我的真实代码更复杂,我需要使用“nativeQuery”。以上是关于我可以在 JpaRepository nativeQuery 中使用枚举参数吗?的主要内容,如果未能解决你的问题,请参考以下文章
如何将对象从一个 JpaRepository 转换为另一个 JpaRepository
是否有 JpaRepository 方法可以在用户名条件下保存提供的密码?
是否可以使用 JpaRepository 在 Spring Data JPA 中使用“TRUNCATE”?还是比标准 deleteAll() 更有效的方法?
spring data jpa中实现JpaRepository接口的repository可以返回sortedset吗?