Annotation to Filter Results of a @Onetomany Association

annotation to filter results of a @OneToMany association

It is not supported by JPA but if you are using hibernate as JPA provider then you can use annotation @FilterDef and @Filter.

Hibernate Core Reference Documentation

Hibernate3 has the ability to pre-define filter criteria and attach
those filters at both a class level and a collection level. A filter
criteria allows you to define a restriction clause similar to the
existing "where" attribute available on the class and various
collection elements. These filter conditions, however, can be
parameterized. The application can then decide at runtime whether
certain filters should be enabled and what their parameter values
should be. Filters can be used like database views, but they are
parameterized inside the application.

Exemple

@Entity
public class A implements Serializable{
@Id
@Column(name = "REF")
private int ref;

@OneToMany
@JoinColumn(name = "A_REF", referencedColumnName = "REF")
@Filter(name="test")
private Set<B> bs;
}

@Entity
@FilterDef(name="test", defaultCondition="other = 123")
public class B implements Serializable{
@Id
@Column(name = "A_REF")
private int aRef;

@Id
@Column(name = "OTHER")
private int other;
}

Session session = entityManager.unwrap(Session.class);
session.enableFilter("test");
A a = entityManager.find(A.class, new Integer(0))
a.getb().size() //Only contains b that are equals to 123

JPA one-to-many filtering

AFAIK there is no portable JPA-based way to do this. A clean, however a little bit inefficient, solution would be to do everything on Java-side and create a getter getActiveSystemproperties() that manually iterates over mapped systempropertys and returns an immutable set of active properties.

Using @Filter with @ManyToOne relation

First, you have to create the @FilterDef somewhere (this defines the available parameters, and the default condition), then define the @Filter on a particular class.

Finally, have to enable the filter on the Session object, and set any parameters it requires. Filters are not enabled in hibernate sessions by default. You have to enable the specific ones you want once the session is opened.

See section 19.1 for an example: 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 ... {
}

Then somewhere in your dao code:

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

You should not have to touch any hql. Whenn you enable the filter, all classes which have an actual @Filter defined for it will automatically apply the condition.

There are additional ways to do things for collections, and i suggest you read the documentation referenced above for that. But in general, you can provide the @Filter annotation classes and on collection properties.

Spring JPA fetch subset of OneToMany relation

The @Fetch annotation will not help you as it's affect fetching behavior not filtering.

I guess you can try to use @Filter annotation here.

  1. You can correct your mapping in the following way:
@Entity(name = "articles")
data class Article(

// ...

@OneToMany
@Filter(
name="commentUser",
condition="username = :name"
)
val comments: List<Comment>,

)

  1. Then you can enable the filter:
entityManager
.unwrap( Session.class )
.enableFilter("commentUser")
.setParameter("name", "user_z");

  1. And then call your ArticlesRepository.findArticlesByUsername method.

See also this section of the hibernate documentation.

P.S. I am not familiar with Kotlin, so the syntax may require correction.



Related Topics



Leave a reply



Submit