如何解决有什么方法可以使用JPA查询更新SET类型列?
我想做的是通过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
// newRoles : Set<Role>
// Error: IllegalArgumentException
query.set(QStaff.Staff.roles,newRoles));
// Of course,compile error
query.set(QStaff.Staff.roles,Set.of(newRoles)));
解决方法
自定义类型需要通过JPA实现中的自定义类型进行映射。对于Hibernate,这是通过“用户类型”界面进行的。为了通过QueryDSL使用扩展类型,您需要为其创建自定义表达式类型。此外,对于您要支持的任何操作(例如set包含,相等),您都必须注册自定义函数。可以完成,但不能使用常规API。您最好关闭对元模型的规范化,而使用@ElementCollection
。但是,如果您坚持要上班,这里有一些提示:
-
hibernate-types
是一个广受欢迎的项目,为Hibernate实现了许多自定义类型。它没有实现SET,但是您可以使用数组的实现作为基础。 -
hibernate-types-querydsl-apt
是一个项目,用于扩展某些自定义类型的QueryDSL元模型生成。您可能还应该模仿该存储库中的任何集。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。