Hibernate @Filter collection of listings

I need to figure out how to apply annotation-based filtering using a list of enumeration options defined as:

@Column(name = "target_status") @Enumerated(EnumType.STRING) @Type(type="PGEnumConverter", parameters = { @Parameter(name = "enumClassName", value = "com.company.model.campaign.CampaignTarget$Status") }) private Status targetStatus; 

So my @FilterDef looks like this:

  @FilterDef(name="filterCampaignTargetByStatuses", defaultCondition="target_status in (:statuses)", parameters = @ParamDef(name = "statuses", type = "string")) 

And when I turn on the filter, it looks like this:

  session.enableFilter("filterCampaignTargetByStatuses"). setParameterList("statuses", statuses); 

And the error I get from sleep mode:

  org.hibernate.HibernateException: Incorrect type for parameter [statuses] 

The data is in PostgreSQL and type definition:

 CREATE TYPE statuscmp AS ENUM ('ACTIVE','INACTIVE','PAUSED','DRAFT','SCHEDULED','ENDED','ARCHIVED'); 

I saw a lot of SO questions about how to fulfill query and filter criteria with respect to a single Enum value, but so far there is no filtering by a set of Enum values. Is there a way to explicitly specify individual values?

+6
source share
1 answer

You do not need to "distinguish" the value at all, in fact you just need to pass the values ​​in the form that they store.

If we assume that your field was annotated only as @Enumerated(EnumType.STRING) , the column will be a simple varchar field. (Matching java type with postgres enumeration is another big topic.)

If now you want to compare your list of Status enum instances with the associated string values ​​in db, pass it as a collection of strings, in other words, call it toString() if it is java enum .

eg. this was your listing:

 public enum EntityStatus { A, B, C; } 

That was your essence:

 import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import org.hibernate.annotations.Filter; import org.hibernate.annotations.FilterDef; import org.hibernate.annotations.ParamDef; @Entity @FilterDef(name = "byMultipleStates", defaultCondition = "status in (:states)", parameters = @ParamDef(name = "states", type = "string")) @Filter(name = "byMultipleStates", condition = "status in (:states)") public class StatusEntity { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @Enumerated(EnumType.STRING) private EntityStatus status; public long getId() { return id; } public EntityStatus getStatus() { return status; } public void setStatus(EntityStatus status) { this.status = status; } } 

This could be your filtering code:

 public List<StatusEntity> filterByStates(final Set<EntityStatus> states) { final Session hibernateSession = entityManager.unwrap(Session.class); hibernateSession.enableFilter("byMultipleStates").setParameterList("states", states.stream().map(state -> state.toString()).collect(Collectors.toList())); final Query query = hibernateSession.createQuery("SELECT e FROM StatusEntity e"); return query.list(); } 

Or on the way to Java 8:

 public List<StatusEntity> filterByStates(final Set<EntityStatus> states) { final Set<String> statesAsString = new HashSet<>(); for (final EntityStatus state : states) { statesAsString.add(state.toString()); } final Session hibernateSession = entityManager.unwrap(Session.class); hibernateSession.enableFilter("byMultipleStates").setParameterList("states", statesAsString); final Query query = hibernateSession.createQuery("SELECT e FROM StatusEntity e"); return query.list(); } 

Thus, only filtering is possible for a set of values.

0
source

All Articles