休眠过滤器不适用于联接实体 [英] Hibernate filter does not apply for join entity

查看:54
本文介绍了休眠过滤器不适用于联接实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解休眠过滤器,我认为即使查询不是从过滤的实体开始的,过滤器仍适用,并且只要我加入该过滤器就可以使用.

我的实体:

  @Table(名称="SPM_SECTION",模式="TEST")@GenericGenerator(名称="MODSEC_ID.GEN",策略="uuid2")公共类ModuleSection实现了Serializable {私人AcademicClass AcademicClass;@ManyToOne(获取= FetchType.LAZY)@JoinColumn(名称="CLASS_ID")公共AcademicClass getAcademicClass(){返回AcademicClass;}公共无效setAcademicClass(AcademicClass AcademicClass){this.academicClass = AcademicClass;}}@实体@GenericGenerator(名称="AC_CLASS_ID.GEN",策略="uuid2")@Where(clause ="1 = 1")@FilterDef(名称= Resources.SECURITY_FILTER_NAME,参数= {@ ParamDef(名称= Resources.SECURITY_FILTER_PARAMETER,类型="string")}))@Filter(名称= Resources.SECURITY_FILTER_NAME,条件=((:" + Resources.SECURITY_FILTER_PARAMETER +)"中的DISCRIMINATOR_ID))@Table(name ="ACADEMIC_CLASS",schema ="TEST",uniqueConstraints = @UniqueConstraint(columnNames = {"OUS_ID","YEAR_ID","PERIOD_ID","SHIFT_ID","SEMESTER","CODE"}))公共类AcademicClass实现java.io.Serializable {//我尝试通过在这里建立关联,也尝试不使用它.私有Set< ModuleSection>区段=新的HashSet<>(0);@OneToMany(获取= FetchType.LAZY,mappedBy ="academicClass")公共Set< ModuleSection>getSections(){返回this.sections;}public void setSections(Set< ModuleSection>部分){this.sections =部分;}} 

通过拦截器启用过滤器,并从数据库中获取参数列表以确保安全性.

当我执行这样的查询时:

  em.createQuery(从"AcademicClass acc ......."中选择acc,"AcademicClass.class").getResultList(); 

已应用过滤器.但是我也希望当我的查询从ModuleSection开始时应用过滤器:

  em.createQuery(从ModuleSection中选择ms ms join ms.academicClass acc",AcademicClass.class).getResultList(); 

在上面的查询中,未应用过滤器.

ModuleSection实体中的AcademicClass可为空,但在上述情况不起作用的情况下,我还有其他不为null的实体.

我也尝试在模块部分的属性中应用@Filter或@FilterJoinTable,但是没有运气:

  @ManyToOne(获取= FetchType.LAZY)@JoinColumn(名称="CLASS_ID")@Filter(名称= Resources.SECURITY_FILTER_NAME,条件=((:" + Resources.SECURITY_FILTER_PARAMETER +)"中的DISCRIMINATOR_ID))@FilterJoinTable(name = Resources.SECURITY_FILTER_NAME,condition ="DISCRIMINATOR_ID in(:: + Resources.SECURITY_FILTER_PARAMETER +")))公共AcademicClass getAcademicClass(){返回AcademicClass;} 

我的问题:过滤器是否仅用于过滤from子句中的实体?筛选器是否适用于联接实体?如果要实现上述功能,是否还应该在ModuleSection中添加DISCRIMINATOR_ID并将过滤器添加到该实体,从那里开始查询?

解决方案

hibernate文档中对此保持沉默,但看起来 @Filter 仅应用于 from 子句.

假设我们具有以下映射:

  @Entity@Table(名称="ACADEMIC_CLASS")@FilterDef(name ="isAccessible",参数= @ParamDef(名称=秒",type ="string"))@筛选(name ="isAccessible",条件="{:sec)中的{acclass} .discriminator_id",别名= {@SqlFragmentAlias(别名="acClass",table ="TEST_SCHEMA.ACADEMIC_CLASS")})公共课学术课{@ID@Column(名称="class_id")私人Long ID;@OneToMany(获取= FetchType.LAZY,mappedBy ="academicClass")私有Set< ModuleSection>部分;//吸气剂/吸气剂}@实体@Table(名称="SPM_SECTION")公共类ModuleSection{@ID@Column(名称="sec_id")私人Long ID;@ManyToOne(获取= FetchType.LAZY)@JoinColumn(名称="sec_class_id")私人AcademicClass AcademicClass;//吸气剂/吸气剂} 

当我们运行以下查询时:

 会话.enableFilter("isAccessible").setParameter("sec","A1");List< AcademicClass>类= session.createQuery(从ModuleSection ms中选择ac加入ms.academicClass ac",学术班级).getResultList(); 

未应用过滤器.它应该在

,结果将生成以下查询:

 休眠:/* 选择交流电从ModuleSection毫秒,学术课在哪里ms.academicClass = ac*/选择Academiccl1_.class_id作为class_id1_0_来自TEST_SCHEMA.SPM_SECTION模块ect0_交叉加入TEST_SCHEMA.ACADEMIC_CLASS Academiccl1_其中(?)中的Academiccl1_.discriminator_id和模块ect0_.sec_class_id = academiccl1_.class_id 

因此,作为一种解决方法,您可以通过这种方式重写查询.

@FilterJoinTable 注释仅当您在父实体和子表之间具有链接表时才能使用.

I am trying to understand hibernate filters, i thought that the filter is applied even if the query is not started from the filtered entity and can be applied if i just join to it.

My entities:

@Table(name = "SPM_SECTION", schema = "TEST")
@GenericGenerator(name = "MODSEC_ID.GEN", strategy = "uuid2")
public class ModuleSection implements Serializable {

private AcademicClass academicClass;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CLASS_ID")
    public AcademicClass getAcademicClass() {
        return academicClass;
    }

    public void setAcademicClass(AcademicClass academicClass) {
        this.academicClass = academicClass;
    }
    
}

@Entity
@GenericGenerator(name = "AC_CLASS_ID.GEN", strategy = "uuid2")
@Where(clause="1=1")
@FilterDef(name= Resources.SECURITY_FILTER_NAME, parameters={@ParamDef(name=Resources.SECURITY_FILTER_PARAMETER, type="string")})
@Filter(name=Resources.SECURITY_FILTER_NAME, condition = "DISCRIMINATOR_ID in (:"+Resources.SECURITY_FILTER_PARAMETER+")")
@Table(name = "ACADEMIC_CLASS", schema = "TEST", uniqueConstraints = @UniqueConstraint(columnNames = {"OUS_ID", "YEAR_ID",
        "PERIOD_ID", "SHIFT_ID", "SEMESTER", "CODE" }))
public class AcademicClass implements java.io.Serializable {

    //I tried by having the association here, i also tried without it.
    private Set<ModuleSection> sections = new HashSet<>(0);
    
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "academicClass")
    public Set<ModuleSection> getSections() {
        return this.sections;
    }

    public void setSections(Set<ModuleSection> sections) {
        this.sections = sections;
    }

}

The filter is enabled through an interceptor and the parameter list is fetched from the database for security.

When i execute a query like this:

em.createQuery("select acc from AcademicClass acc ...........", AcademicClass.class)
.getResultList();

the filter is applied. But i also want the filter to be applied when my query starts from ModuleSection:

em.createQuery("select ms from ModuleSection ms join ms.academicClass acc", AcademicClass.class)
.getResultList();

In above query the filter is not applied.

The academicClass in ModuleSection entity is nullable but i also have other entities not null where the above case does not work.

I also tried to apply the @Filter or @FilterJoinTable in module section property with no luck:

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CLASS_ID")
    @Filter(name=Resources.SECURITY_FILTER_NAME, condition = "DISCRIMINATOR_ID in (:"+Resources.SECURITY_FILTER_PARAMETER+")")
    @FilterJoinTable(name=Resources.SECURITY_FILTER_NAME, condition = "DISCRIMINATOR_ID in (:"+Resources.SECURITY_FILTER_PARAMETER+")")
    public AcademicClass getAcademicClass() {
        return academicClass;
    }

My questions: Are filters meant to filter only the entity in the from clause? does the filter apply in join entities? If I want to implement the above should I also add a DISCRIMINATOR_ID in ModuleSection and add the filter to that entity starting the query from there?

解决方案

There is a silence about it in the hibernate documentation, but it looks like this is true that @Filter is applied only to the from clause.

Assuming that we have the following mapping:

@Entity
@Table(name = "ACADEMIC_CLASS")
@FilterDef(
   name="isAccessible",
   parameters = @ParamDef(
      name="sec",
      type="string"
   )
)
@Filter(
   name="isAccessible",
   condition="{acClass}.discriminator_id in (:sec)",
   aliases = {
      @SqlFragmentAlias(alias = "acClass", table= "TEST_SCHEMA.ACADEMIC_CLASS")
   }
)
public class AcademicClass
{
   @Id
   @Column(name = "class_id")
   private Long id;

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "academicClass")
   private Set<ModuleSection> sections;

   // getters/setters
}

@Entity
@Table(name = "SPM_SECTION")
public class ModuleSection
{
   @Id
   @Column(name = "sec_id")
   private Long id;

   @ManyToOne(fetch = FetchType.LAZY)
   @JoinColumn(name = "sec_class_id")
   private AcademicClass academicClass;

   // getters/setters
}

When we run the following query:

session
   .enableFilter("isAccessible")
   .setParameter("sec", "A1");

List<AcademicClass> classes = session.createQuery(
    "select ac from ModuleSection ms join ms.academicClass ac",
    AcademicClass.class
).getResultList();

The filter is not applied. It should happen in the JoinSequence.toJoinFragment. The filterCondition is empty in this case.

But for the rewritten in the following way query:

List<AcademicClass> classes = session.createQuery(
    "select ac from ModuleSection ms, AcademicClass ac where ms.academicClass = ac",
    AcademicClass.class
).getResultList();

We will have:

and as result the following query will be generated:

Hibernate: 
/* select
     ac 
   from
      ModuleSection ms,
      AcademicClass ac 
   where
        ms.academicClass = ac
*/
select
   academiccl1_.class_id as class_id1_0_ 
from TEST_SCHEMA.SPM_SECTION modulesect0_ cross 
join TEST_SCHEMA.ACADEMIC_CLASS academiccl1_ 
where academiccl1_.discriminator_id in (?) 
  and modulesect0_.sec_class_id=academiccl1_.class_id

So, as a workaround you can rewrite your query in this way.

The @FilterJoinTable annotation can be used only if you have a link table between the parent entity and the child table.

这篇关于休眠过滤器不适用于联接实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆