简体   繁体   English

Hibernate @Filter枚举集合

[英]Hibernate @Filter collection of enums

I need to figure out how to apply annotation-based filtering with a parameter list of enums 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看起来像这样:

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

And when I enable the filter it looks like this: 当我启用过滤器时,它看起来像这样:

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

And the Error that I get from hibernate is: 我从hibernate获得的错误是:

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

The data is in PostgreSQL and the definition of the type: 数据在PostgreSQL中并且类型的定义如下:

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

I've seen a lot of SO questions about how to do criteria queries and filters against a single Enum value, but none yet about filtering on a set of Enum values. 我已经看到很多关于如何针对单个Enum值进行标准查询和过滤的SO问题,但是还没有关于对一 Enum值进行过滤的问题。 Is there a way to explicitly cast the individual values? 有没有办法明确地投射个别价值观?

You don't have to "cast" the value in general, in fact you just have to pass the values in the form they are stored. 您不必一般“强制转换”该值,实际上您只需要以它们存储的形式传递值。

If we assume your field was only annotated as @Enumerated(EnumType.STRING) the column would be a plain varchar field. 如果我们假设您的字段仅注释为@Enumerated(EnumType.STRING)该列将是纯varchar字段。 (Mapping a java type to a postgres enum is another big topic.) (将java类型映射到postgres枚举是另一个重要主题。)

If you now want to compare your list of Status enum instances with the related string values in the db, pass it as collection of strings, in other words, call it's toString() method if it's a java enum . 如果您现在想要将Status枚举实例列表与db中的相关字符串值进行比较,请将其作为字符串集合传递,换句话说,如果它是java enum ,则调用它的toString()方法。

Eg this was your enum: 这是你的枚举:

public enum EntityStatus {
    A, B, C;
}

This was your Entity: 这是你的实体:

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 code to filter: 这可能是您要过滤的代码:

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 in the way before Java 8: 或者在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();
}

So just filtering for a collection of values is possible. 因此,只需过滤一组值即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM