2015-07-23 17 views
6

ho bisogno di capire come applicare il filtro di annotazione-based con una lista di parametri di enumerazioni definito come:Hibernate @Filter collezione di enumerazioni

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

Quindi il mio @FilterDef assomiglia a questo:

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

E quando abilitare il filtro che assomiglia a questo:

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

e l'errore che ottengo fro m Hibernate è:

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

I dati sono in PostgreSQL e la definizione del tipo:

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

Ho visto un sacco di SO domande su come fare criteri di query e filtri contro un singolo Valore enumerato, ma nessuno ancora sul filtraggio su un imposta valori di Enum. C'è un modo per esprimere esplicitamente i singoli valori?

risposta

0

Non è necessario "trasmettere" il valore in generale, infatti è sufficiente passare i valori nel modulo in cui sono memorizzati.

Se si assume che il proprio campo sia stato annotato come @Enumerated(EnumType.STRING), la colonna sarebbe un campo varchar normale. (Mappatura un tipo Java per un enum postgres è un altro grande tema.)

Se ora si vuole confrontare la vostra lista di Status Enumera istanze con i valori di stringa connessi nella db, passarlo come insieme di stringhe, in altri parole, chiama il metodo toString() se è un java enum.

E.g. questo è stato il tuo enum:

public enum EntityStatus { 
    A, B, C; 
} 

Questa era la tua Entità:

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

} 

Questo potrebbe essere il codice per filtrare:

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

O nel modo prima di 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(); 
} 

Quindi basta filtrare per un insieme di v il alues ​​è possibile.