Thursday 18 May 2017

AdditionalCriteria

Small followup of From Hibernate to Eclipselink1 post.

I am not entirely satisfied about the AdditionalCriteria4 thingy. I find it a chore to have to set a parameter on the EntityManager all the time to enable/disable it.

Biggest issue for me is that parameters set on the EntityManager are required. If they are omitted, an exception is thrown when querying.

Current solution in my software:
Turn the AdditionalCriteria on or off by means of a parameter that needs to be set on the EntityManager.

Looks like this:
Setting the parameter activePersonFilter can be done on the EntityManager as follows:
@PersistenceContext(properties =
{
  @PersistenceProperty(name = "activePersonFilter", value = "0"),
  @PersistenceProperty(name = "sundaydateFilter", value = "")
})
private EntityManager em;
Or
entityManager.setProperty("activePersonFilter", 0);

Other solutions

There are some other solutions.
  1. You can remove the additionalCriteria (set it to "") in a subclass, and use the subclass specifically. See [2].
  2. You can customize any mapping in EclipseLink and add the requirements/conditions that you need. See [3].
  3. I could just decide to create a view on the offending database table. Then create two entities. Sounds very similar to the first option.
  4. I could solve the problem in software. Just have EclipseLink not filter anything. (Which is silly, I don't wish for my ORM to get the 1000 persons in the room from the database, if there are say only three persons active.)
  5. I could remove the collection entirely, and retrieve the required Persons using a NamedQuery. (Which is bogus. I like the ORM to deal with this for me, instead of having to do it myself. It's what the ORM is for.)

Customizing a Mapping

I have recently decided to try to customize the mapping specifically in Entities that have collections containing instances of Person class. That way I have more control. See reference [3] on how this works.

It requires a @Customizer annotation.

For instance, in a Room I only wish to see the active persons.

This requires me to define the PersonsFilterForRoom as follows.
"persons"
the name of the field that contains the collection
"room"
the name of the field in the Entity of the collection
"id"
the name of the field in the Room entity that identifies it
It works pretty good.

Note

I also noticed that this way I could have two (Lazy! That's the important bit!) Collections in the same Entity at the same time referring to the same Person. One will contain all Persons and one will contain only the Active Persons.

This is ideal, for instance for Guilds.

Like so:
This way the customizer PersonsFilterForGuild is designed to only work on the activeMembers collection.

I like it!

References

[1] From Hibernate to EclipseLink
http://randomthoughtsonjavaprogramming.blogspot.nl/2014/07/from-hibernate-to-eclipselink.html
[2] StackOverflow - Disable additional criteria only in some entity relations
http://stackoverflow.com/questions/37419406/disable-additional-criteria-only-in-some-entity-relations
[3] Mapping Selection Criteria
https://wiki.eclipse.org/EclipseLink/Examples/JPA/MappingSelectionCriteria
[4] JPA Extention in EclipseLink - @AdditionalCriteria
https://www.eclipse.org/eclipselink/documentation/2.6/jpa/extensions/annotations_ref.htm#additionalcriteria
Customizing EclipseLink JPA/ORM Relationship Joins
http://onpersistence.blogspot.nl/2008/01/customizing-eclipselink-jpaorm.html

No comments:

Post a Comment