我正在使用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
Bar
group = :group
的所有@Filter(name = "groupFilter", condition = "group = :group")
?这应该是一个安全约束。
尝试在bar
的属性Foo
设置{{1}}但不起作用。 Hibernate是否支持此功能,或者Filter仅适用于实体/集合级别?我是否必须更改所有HQL以添加此安全约束?
答案 0 :(得分:2)
首先,您必须在某处创建@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 ... {
}
然后在你的代码中的某个地方:
session.enableFilter("groupFilter").setParameter("group", group);
你不应该触摸任何hql。当您启用过滤器时,所有为其定义了实际@Filter的类将自动应用该条件。
还有其他方法可以为集合做事,我建议您阅读上面引用的文档。但一般来说,您可以提供@Filter注释类和集合属性。
答案 1 :(得分: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()
返回CollectionType
或EntityType
。
前者代表声明,例如:
@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
关系,则可以应用过滤器: