2015-07-23 24 views
6

ich brauche, um herauszufinden, wie Annotation basierte Filterung mit einer Parameterliste von Aufzählungen wie definiert anzuwenden:Hibernate @filter Sammlung von Aufzählungen

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

Also meine @FilterDef sieht wie folgt aus:

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

Und wenn ich den Filter zu aktivieren sieht es wie folgt aus:

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

Und die Fehler, die ich her bekommen m Hibernate ist:

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

Die Daten in PostgreSQL ist und die Definition des Typs:

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

ich eine Menge SO Fragen zu gesehen haben, wie Kriterien zu tun Abfragen und Filter gegen einen einzigen Enum-Wert, aber noch keine Filterung auf Set von Enum-Werten. Gibt es eine Möglichkeit, die einzelnen Werte explizit zu formulieren?

Antwort

0

Sie müssen den Wert im Allgemeinen nicht "werfen", in der Tat müssen Sie nur die Werte in der Form übergeben, in der sie gespeichert sind.

Wenn wir annehmen, dass Ihr Feld nur als @Enumerated(EnumType.STRING) annotiert wurde, wäre die Spalte ein einfaches varchar-Feld. (eine Java-Typ zu einer Postgres-Enumeration Mapping ist ein weiteres großes Thema.)

Wenn Sie nun möchten, dass Ihre Liste der Status Enum-Instanzen mit den entsprechenden String-Werte in der db, übergeben Sie es als Sammlung von Zeichenfolgen vergleichen, in anderen Wörter, rufen Sie es ist toString() Methode, wenn es ein Java enum ist.

z. dies war Ihr Enum:

public enum EntityStatus { 
    A, B, C; 
} 

Das war dein 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; 
    } 

} 

Dies könnte Ihr Code zu filtern sein:

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(); 
} 

Oder in der Art und Weise vor 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 nur für eine Sammlung von v filtern Vorteile sind möglich.

Verwandte Themen