【问题标题】:Is there any way to update SET type column using JPA query?有没有办法使用 JPA 查询更新 SET 类型列?
【发布时间】:2020-12-22 20:05:23
【问题描述】:

我想做的是通过 JPA 查询更新表中的字段。 我将我的 MySQL 表设置为 SET 类型。

create table staff (
   id    BIGINT,
...
   roles  SET('A', 'B', 'C')    not null,
...
)

和类

public class Staff {
    private Long id;
    @Converter(someConverterHere.class)
    private Set<Role> roles;
}

我尝试像下面这样更新这个字段

@Modifying
@Query("update Staff s SET s.roles = :newRoles where s.id = :id")
Integer updateStaffRoles(@Param("id") Long id, @Param("newRoles") Set<Role> newRoles);

然后,当我将这个 Set.of(Role.A, Role.B) 作为参数时,它向我显示了这样的错误,

Caused by: java.lang.IllegalArgumentException: Parameter value [A] did not match expected type [java.util.Set (n/a)]
at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:54)
at org.hibernate.query.spi.QueryParameterBindingValidator.validate(QueryParameterBindingValidator.java:27)
at org.hibernate.query.internal.QueryParameterBindingImpl.validate(QueryParameterBindingImpl.java:90)
at org.hibernate.query.internal.QueryParameterBindingImpl.setBindValue(QueryParameterBindingImpl.java:55)
at org.hibernate.query.internal.QueryParameterBindingsImpl.expandListValuedParameters(QueryParameterBindingsImpl.java:636)
at org.hibernate.query.internal.AbstractProducedQuery.doExecuteUpdate(AbstractProducedQuery.java:1629)
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1612)
at org.springframework.data.jpa.repository.query.JpaQueryExecution$ModifyingExecution.doExecute(JpaQueryExecution.java:238)
at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154)
at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor$QueryMethodInvoker.invoke(QueryExecutorMethodInterceptor.java:195)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152)
at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
... 81 common frames omitted

似乎 jpa 查询生成器验证了 newRoles 中的所有单个值,并将其类型与 Staff.roles 的类型进行比较,这不可能是真的(角色和设置)

有没有办法解决这个问题?我找不到任何解决方案。

依赖

  • org.springframework.data:spring-data-jpa:2.3.2.RELEASE

================================================ ======

临时解决方案: 我将参数类型从 Set 更改为 Set 并且它有效。而现在,这个问题在使用 QueryDsl 时成为问题。使用querydsl的“set”,这个问题又出现了:(

查询dsl

// newRoles : Set<Role>
// Error: IllegalArgumentException
query.set(QStaff.Staff.roles, newRoles));

// Of course, compile error
query.set(QStaff.Staff.roles, Set.of(newRoles)));

【问题讨论】:

    标签: mysql spring spring-data-jpa querydsl


    【解决方案1】:

    自定义类型需要通过 JPA 实现中的自定义类型进行映射。对于通过 User Type 界面的 Hibernate。为了通过 QueryDSL 使用扩展类型,您需要为其创建自定义表达式类型。此外,对于您想要支持的任何操作(例如 set contains、相等),您必须注册自定义函数。它可以完成,但不能使用常规 API。您可能最好对元模型进行非规范化并改用@ElementCollection。但是,如果您坚持要上班,这里有一些提示:

    • hibernate-types 是一个广受欢迎的项目,它为 Hibernate 实现了许多自定义类型。它没有实现 SET,但您可以使用数组的实现作为基础。
    • hibernate-types-querydsl-apt 是一个为某些自定义类型扩展 QueryDSL 元模型生成的项目。您可能还应该为集合模仿该存储库中的任何内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-05
      • 2011-03-04
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多