You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate @Filter注解失效排查及多语言映射优化咨询

补充实体映射

TranslationValue实体

@Entity
@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Table(name = "translations_values")
@NamedQuery(name = "TranslationValue.findAll", query = "SELECT t FROM TranslationValue t")
public class TranslationValue implements Identifiable, Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "identifier")
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @JsonView(View.class)
    private Integer identifier;

    @Column(name = "key", insertable = false, updatable = false)
    private Integer keyIdentifier;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "key")
    private TranslationKey key;

    @Column(name = "language", insertable = false, updatable = false)
    private Integer languageIdentifier;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "language")
    private Language language;

    @Column(name = "value")
    @Lob
    private String value;

    // Getters & Setters
    
}

TranslationKey实体

@Entity
@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Table(name = "translations_keys")
@NamedQuery(name = "TranslationKey.findAll", query = "SELECT t FROM TranslationKey t")
public class TranslationKey implements Identifiable, Serializable {

    private static final long serialVersionUID = 1L;

    @Column(name = "identifier")
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer identifier;

    @CriteriaParticipant
    @Column(name = "constraint")
    private Integer metadata;

    @OneToMany(mappedBy = "key")
    @Fetch(FetchMode.SELECT)
    @BatchSize(size = 1000)
    private List<TranslationValue> values;

    // Getters and Setters

}

解决方案

问题1:@Filter未生效的修复

你把@FilterDef定义在了Post实体上,但过滤条件中的language字段属于TranslationValue实体,Hibernate无法在Post的上下文里识别这个字段,导致过滤器失效。

正确修改方式:

  1. 移除Post实体上的@FilterDef,将其移到TranslationValue实体,并直接在该实体上定义过滤条件:
@Entity
@Data
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Table(name = "translations_values")
@NamedQuery(name = "TranslationValue.findAll", query = "SELECT t FROM TranslationValue t")
@FilterDef(name = "langfilter", parameters = @ParamDef(name = "langid", type = Integer.class))
@Filter(name = "langfilter", condition = "language = :langid")
public class TranslationValue implements Identifiable, Serializable {
    // 其他代码保持不变
}
  1. 在Post实体的nameTranslations关联上,保留@Filter注解引用该过滤器:
@OneToMany(fetch = FetchType.EAGER)
@Filter(name = "langfilter")
@JoinColumn(name = "key", referencedColumnName = "name", insertable = false, updatable = false)
@JsonView(View.class)
private List<TranslationValue> nameTranslations;

修改后,Hibernate会在关联查询TranslationValue时自动应用过滤条件,生成的SQL会带上language = 3的限制。

注意:Hibernate 6+版本要确保过滤器参数类型和实体字段类型严格匹配,这里language是Integer类型,参数配置正确。

问题2:是否可以用@ManyToOne映射

完全可以。因为每个帖子对应一个翻译键,而指定语言下每个翻译键只会有一条翻译值,所以可以将nameTranslations从List<TranslationValue>改为TranslationValue,并使用@ManyToOne映射,配合过滤器获取指定语言的翻译值:

修改后的Post实体关联代码:

@ManyToOne(fetch = FetchType.EAGER)
@Filter(name = "langfilter")
@JoinColumn(name = "name", referencedColumnName = "key", insertable = false, updatable = false)
@JsonView(View.class)
private TranslationValue nameTranslation;

这种映射更贴合你的业务场景,查询时只会加载对应语言的那一条翻译值(返回一个或零个结果)。


内容的提问来源于stack exchange,提问作者Emax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:37:04