2016-08-31 5 views
0

Meine Anwendung verwendet Hibernate 5.02 und Wildfly 10 mit einer PostgreSQL 9.5-Datenbank. Ich versuche, einen Filter für eine @ OneToMany-Sammlung zu aktivieren, die in einer Entität enthalten ist, die über eine NamedQuery erstellt wird. Leider scheint es, als ob der Filter einfach ignoriert wird. Hier sind die verschiedenen Komponenten, die zum leichteren Lesen redigiert wurden.Hibernate-Filter wird ignoriert

@NamedNativeQueries({ 
@NamedNativeQuery(
     name = "getAnalystProcess", 
     query = "SELECT * FROM analysis.analystprocess WHERE id = :processId", 
     resultClass = AnalystProcessEntity.class 
)}) 
@FilterDef(
    name = "analystProcessUnanalyzedMsgsFilter", 
    parameters = { @ParamDef(name = "processIds", type = "integer"), @ParamDef(name = "analystIds", type = "integer") }) 
@Filter(name = "analystProcessUnanalyzedMsgsFilter", condition = "analystprocess_id IN (:processIds) AND id NOT IN (SELECT msg_id FROM analysis.analyzedmsg WHERE analyst_id IN (:analystIds) AND analystprocess_id IN (:processIds)) ORDER BY process_msg_id") 
@Entity 
@Table(name = "analystprocess", schema = "analyst") 
public class AnalystProcessEntity implements JPAEntity { 

public static final String GET_PROCESS = "getAnalystProcess"; 
public static final String MSG_FILTER = "analystProcessUnanalyzedMsgsFilter"; 
public static final String MSG_FILTER_PROC_ID_PARAM = "processIds"; 
public static final String MSG_FILTER_ANALYST_ID_PARAM = "analystIds"; 

private static final long serialVersionUID = 1L; 

... 

@OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "process") 
@OrderColumn(name = "process_msg_id") 
@LazyCollection(LazyCollectionOption.EXTRA) 
private List<MsgEntity> msgList; 

@Entity 
@Table(name = "msg", schema = "analyst") 
public class MsgEntity implements JPAEntity { 

... 

@ManyToOne(cascade = CascadeType.ALL, optional = false) 
@JoinColumn(name = "analystprocess_id", referencedColumnName = "id") 
private AnalystProcessEntity process; 

@Column(name = "process_msg_id") 
private Integer processMsgId; 

private void buildAnalystProcess() { 
    LOG.info("Building AnalystProcessEntity"); 
    analystUser.getJdbcSession().enableFilter(AnalystProcessEntity.MSG_FILTER) 
       .setParameter(AnalystProcessEntity.MSG_FILTER_PROC_ID_PARAM, analystProcessId) 
       .setParameter(AnalystProcessEntity.MSG_FILTER_ANALYST_ID_PARAM, analystUser.getId()); 

    Query query = analystUser.getJdbcSession().getNamedQuery(AnalystProcessEntity.GET_PROCESS) 
      .setParameter("processId", analystProcessId); 

//  Query query = analystUser.getJdbcSession().createNativeQuery("SELECT * FROM analysis.analystprocess WHERE id = :processId") 
//     .setParameter("processId", analystProcessId) 
//     .addEntity(AnalystProcessEntity.class); 

    analystProcess = (AnalystProcessEntity) query.getSingleResult(); 

CREATE TABLE analysis.analystprocess (
     id SERIAL PRIMARY KEY, 
     name TEXT NOT NULL UNIQUE, 
     description TEXT, 
     created_date TIMESTAMP NOT NULL DEFAULT now(), 
     ... 
); 

CREATE TABLE analysis.msg (
     id SERIAL PRIMARY KEY, 
     analystprocess_id INTEGER NOT NULL REFERENCES analysis.analystprocess(id) ON DELETE CASCADE ON UPDATE CASCADE, 
     process_msg_id INTEGER NOT NULL, 
     constraint tbl_statusid_analystprocessid unique(status_id, analystprocess_id) 
); 

Wie oben gesehen, ich habe auch versucht, den Filter auf die AnalystProcessEntity Klasse über createNativeQuery Konstruieren statt getNamedQuery und kein Glück.

Ich habe auch eine defaultCondition mit hartcodierten Werten in die @FilterDef hinzugefügt, nur um zu sehen, ob es die Standardbedingung ausführen würde und es immer noch nicht.

Ich habe den @ Filter über die Entitätsdefinition sowie über die Klassendefinition versucht. Ich bin sogar auf einen Blogpost gestoßen, der es so klingen ließ, als ob die Bedingung auf Entitätsfelder (Variablennamen) und nicht auf Tabellenfelder (Spaltennamen) verweist. Ich versuche, die Namenskonventionen von Java in den Namenskonventionen von Entity und Postgres in der Tabelle einzuhalten, also habe ich versucht, die Referenzen in der Bedingung umzuschalten, aber ohne Erfolg.

Ich habe SQL-Logging eingeschaltet in Hibernate und die Bedingung wird nirgends angezeigt, als ob es einfach ignoriert wird.

Jede Hilfe würde sehr geschätzt werden!

Antwort

0

Also, das Problem war, dass ich @FilterDef auf die falsche Klasse angewendet hatte. Es war meine Annahme, dass, weil ich das AnalystProcessEntity konstruierte, das die MsgEntity-Auflistung enthält (die ich filtere), dass @FilterDef auf die AnalystProcessEntity-Klasse angewendet werden würde. Stattdessen muss es auf die Entität angewendet werden, die es tatsächlich filtert (im Nachhinein 20/20, das ist ziemlich offensichtlich).

Außerdem musste die tatsächliche Bedingung geändert werden, um vollständige Verweise innerhalb der Subselect-Abfrage zu verwenden.

Ich hoffe, das jemand irgendwann hilft ...

@NamedNativeQueries({ 
@NamedNativeQuery(
     name = "getAnalystProcess", 
     query = "SELECT * FROM analysis.analystprocess WHERE id = :processId", 
     resultClass = AnalystProcessEntity.class 
)}) 
@Filter(name = "analystProcessUnanalyzedMsgsFilter", condition = "id NOT IN (SELECT amsg.msg_id FROM analysis.analyzedmsg amsg WHERE amsg.analyst_id IN (:analystIds) AND amsg.analystprocess_id IN (:processIds))") 
@Entity 
@Table(name = "analystprocess", schema = "analyst") 
public class AnalystProcessEntity implements JPAEntity { 

public static final String GET_PROCESS = "getAnalystProcess"; 
public static final String MSG_FILTER = "analystProcessUnanalyzedMsgsFilter"; 
public static final String MSG_FILTER_PROC_ID_PARAM = "processIds"; 
public static final String MSG_FILTER_ANALYST_ID_PARAM = "analystIds"; 

private static final long serialVersionUID = 1L; 

... 

@OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, mappedBy = "process") 
@OrderColumn(name = "process_msg_id") 
@LazyCollection(LazyCollectionOption.EXTRA) 
private List<MsgEntity> msgList; 

@FilterDef(
    name = "analystProcessUnanalyzedMsgsFilter", 
    parameters = { @ParamDef(name = "processIds", type = "integer"), @ParamDef(name = "analystIds", type = "integer") }) 
@Entity 
@Table(name = "msg", schema = "analyst") 
public class MsgEntity implements JPAEntity { 

... 

@ManyToOne(cascade = CascadeType.ALL, optional = false) 
@JoinColumn(name = "analystprocess_id", referencedColumnName = "id") 
private AnalystProcessEntity process; 

@Column(name = "process_msg_id") 
private Integer processMsgId; 

Zusätzlich lief ich in ein anderes Problem mit null ist in der Sammlung erscheinen, trotz der Tatsache, dass ich eine bin mit @OrderColumn, von dem ich dachte, dass es dieses Problem behoben hat. Es scheint, dass mit der Verwendung von @Filter Nullen eingefügt werden anstelle von was gefiltert wurde OUT (ausgeschlossen).