0

我正在使用 Hibernate 3.6.7-Final 和 Spring 3.0.5。

我有这样的实体

@Entity
public class Foo {
    @ManyToOne
    private Bar bar;
}

@Entity
public class Bar {
    @Column
    String group;
}

我如何在 Foo 中使用我@Filter想要获得所有Foo的东西?这应该是一个安全约束。Bargroup = :group

尝试设置@Filter(name = "groupFilter", condition = "group = :group")属性barfromFoo但它不起作用。hibernate 是否支持此功能或过滤器仅适用于实体/集合级别?我是否必须更改所有 HQL 才能添加此安全约束?

4

2 回答 2

1

首先,您必须在某处创建@FilterDef(这定义了可用参数和默认条件),然后在特定类上定义@Filter。

最后,必须在 Session 对象上启用过滤器,并设置它需要的任何参数。默认情况下,休眠会话中未启用过滤器。会话打开后,您必须启用所需的特定功能。

有关示例,请参见第 19.1 节:http: //docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/filters.html

@FilterDef(name="groupFilter", parameters={@ParamDef( name="group", type="string" )})
@Filters(
  { @Filter(name="groupFilter", condition="group = :group") }
)
public class ... {
}

然后在你的 dao 代码中的某个地方:

session.enableFilter("groupFilter").setParameter("group", group);

您不必触摸任何 hql。当您启用过滤器时,为其定义了实际 @Filter 的所有类将自动应用该条件。

还有其他方法可以为集合做事,我建议您阅读上面引用的文档。但一般来说,您可以提供 @Filter 注释类和集合属性。

于 2012-05-22T02:30:35.440 回答
0

使用带有@ManyToOne连接的过滤器的问题来自以下内容。我指的是 Hibernate 4.3.10,因为这是我必须要看的。

相关的 SQL 片段由类org.hibernate.engine.internal.JoinSequence、方法生成toJoinFragment

/**
 * Generate a JoinFragment
 *
 * @param enabledFilters The filters associated with the originating session to properly define join conditions
 * @param includeAllSubclassJoins Should all subclass joins be added to the rendered JoinFragment?
 * @param withClauseFragment The with clause (which represents additional join restrictions) fragment
 * @param withClauseJoinAlias The
 *
 * @return The JoinFragment
 *
 * @throws MappingException Indicates a problem access the provided metadata, or incorrect metadata
 */
public JoinFragment toJoinFragment(
        Map enabledFilters,
        boolean includeAllSubclassJoins,
        String withClauseFragment,
        String withClauseJoinAlias) throws MappingException {

        ...

        final String on = join.getAssociationType().getOnCondition( join.getAlias(), factory, enabledFilters, treatAsDeclarations );

根据定义的关系join.getAssociationType()返回CollectionTypeEntityType

前者代表声明,如:

@OneToMany
private List<MyEntity> myEntities;

后者代表这个:

@ManyToOne
private MyEntity myEntity;

在第一种情况下,使用此方法:

@Override
public String getOnCondition(
        String alias,
        SessionFactoryImplementor factory,
        Map enabledFilters,
        Set<String> treatAsDeclarations) {
    return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters, treatAsDeclarations );
}

而在第二种情况下,该方法如下所示:

@Override
public String getOnCondition(
        String alias,
        SessionFactoryImplementor factory,
        Map enabledFilters,
        Set<String> treatAsDeclarations) {
    if ( isReferenceToPrimaryKey() && ( treatAsDeclarations == null || treatAsDeclarations.isEmpty() ) ) {
        return "";
    }
    else {
        return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters, treatAsDeclarations );
    }
}

这意味着:

  • 当我们在实体定义中有引用的子实体列表时,将无条件地应用过滤器。
  • 当我们有一个引用的子实体时,在满足(不)某些条件时应用过滤器。

根据代码,我认为可以在以下情况下应用过滤器@ManyToOne

  • 在引用的实体中,我们使用不是主键的字段,或者
  • 使用 TREAT 运算符(例如,参见这里或这里)
于 2019-05-17T21:57:50.137 回答