Spring Boot JPA软删除FilterDef参数类型匹配异常求助
解决Spring Boot 3 JPA软删除FilterDef注解类型不匹配问题
问题原因
你使用的是Spring Boot 3.0,它默认集成Hibernate 6.x版本。Hibernate 6对@ParamDef注解的type参数做了API变更:原Hibernate 5中该参数接受字符串类型(如"boolean"),但Hibernate 6要求传入Class<?>类型,这就是导致「Type mismatch: cannot convert from String to Class<?>」异常的根本原因。另外你的代码还存在两个小问题:@FilterDef的name不能为空字符串,实体类的getter/setter存在拼写错误。
解决方案
1. 修改FilterDef和ParamDef注解
将@ParamDef的type值从字符串改为对应的Class对象,同时给@FilterDef设置有效名称,并保证@Filter的name与@FilterDef一致:
@FilterDef(name="deletedFilter", parameters = @ParamDef(name="isDeleted", type = Boolean.class)) @Filter(name="deletedFilter", condition = "deleted = :isDeleted")
2. 修正实体类的Getter/Setter拼写错误
你的实体类中getdeleted()和setdDeleted()存在拼写错误,正确的命名应该符合JavaBean规范:
public Boolean getDeleted() { return deleted; } public void setDeleted(Boolean deleted) { this.deleted = deleted; }
3. 可选:全局开启过滤器(按需)
如果需要全局激活该过滤器,可以添加一个Hibernate配置类:
import org.hibernate.cfg.AvailableSettings; import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.Map; @Configuration public class HibernateConfig { @Bean public HibernatePropertiesCustomizer hibernatePropertiesCustomizer() { return hibernateProperties -> { // 全局开启deletedFilter过滤器 hibernateProperties.put(AvailableSettings.DEFAULT_FILTERS, "deletedFilter"); }; } }
修改后的完整实体类代码
package com.proj.my.model; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; import jakarta.persistence.Id; import jakarta.persistence.Table; import java.sql.Date; import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.Filter; import org.hibernate.annotations.FilterDef; import org.hibernate.annotations.ParamDef; import org.hibernate.annotations.SQLDelete; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @Entity @Table(name="cloud_product_info") @SQLDelete(sql = "UPDATE cloud_product_info SET deleted = true WHERE product_id=?") @FilterDef(name="deletedFilter", parameters = @ParamDef(name="isDeleted", type = Boolean.class)) @Filter(name="deletedFilter", condition = "deleted = :isDeleted") @EntityListeners(AuditingEntityListener.class) @JsonIgnoreProperties(value = {"createdAt", "updatedAt"}, allowGetters = true) public class CloudProduct { @Id private String productId; private String productName; private String productPrice; @CreationTimestamp @Column(updatable = false, name = "created_at") private Date createdAt; private Boolean deleted = Boolean.FALSE; public Boolean getDeleted() { return deleted; } public void setDeleted(Boolean deleted) { this.deleted = deleted; } public CloudProduct(String productId, String productName, String productPrice, Date createdAt, Boolean deleted) { this.productId = productId; this.productName = productName; this.productPrice = productPrice; this.createdAt = createdAt; this.deleted = deleted; } public CloudProduct() {} public String getProductId() { return productId; } public void setProductId(String productId) { this.productId = productId; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public String getProductPrice() { return productPrice; } public void setProductPrice(String productPrice) { this.productPrice = productPrice; } public Date getCreatedAt() { return createdAt; } public void setCreatedAt(Date createdAt) { this.createdAt = createdAt; } }
额外说明
- 如果你只想在特定Repository方法中激活过滤器,可以在Repository接口上使用
@Filter注解并指定参数:import org.springframework.data.jpa.repository.JpaRepository; import org.hibernate.annotations.Filter; import org.hibernate.annotations.FilterDef; import org.hibernate.annotations.ParamDef; import java.util.List; import org.springframework.data.repository.query.Param; @FilterDef(name="deletedFilter", parameters = @ParamDef(name="isDeleted", type = Boolean.class)) public interface CloudProductRepository extends JpaRepository<CloudProduct, String> { @Filter(name="deletedFilter", condition = "deleted = :isDeleted") List<CloudProduct> findByProductName(String productName, @Param("isDeleted") Boolean isDeleted); }
内容的提问来源于stack exchange,提问作者Dadinho2000
相关产品推荐
相关产品推荐

