2016-08-31 145 views
0

我的應用程序使用Hibernate 5.02和Wildfly 10與PostgreSQL 9.5數據庫。我試圖對通過NamedQuery構造的實體中的@OneToMany集合啓用過濾器。不幸的是,它好像只是忽略了過濾器。以下是不同的組件,爲便於閱讀而進行了編輯。被忽略的休眠過濾器

@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) 
); 

如上所見,我還試圖經由createNativeQuery代替getNamedQuery和沒有運氣構建AnalystProcessEntity類過濾器。

我還在硬編碼值中添加了一個defaultCondition到@FilterDef中,以查看它是否會執行默認條件,但它仍然沒有。

我試過@Filter上面的實體定義以及類定義上面。我偶然發現了一篇博客文章,它使得它聽起來像條件​​引用實體字段(變量名稱),而不是表格字段(列名稱)。試圖在表中的Entity和Postgres命名約定中堅持使用Java命名約定,所以我嘗試在條件中切換引用並無濟於事。

我在Hibernate中打開了SQL日誌記錄,並且條件沒有出現在任何地方,就好像它只是簡單地被忽略。

任何幫助將不勝感激!

回答

0

所以,問題是我有@FilterDef適用於錯誤的類。這是我的推測,因爲我正在構建持有MsgEntity集合(我試圖過濾)的AnalystProcessEntity,所以@FilterDef將應用於AnalystProcessEntity類。相反,它需要被應用到它實際上被過濾的實體(後見之明是20/20,這很明顯)。

此外,需要修改實際條件以使用子選擇查詢中的完整引用。

我希望這可以幫助別人在某些時候...

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

此外,我遇到了與空的出現集合中的另一個問題,儘管我使用的是@OrderColumn,我認爲解決了這個問題。看起來,通過使用@Filter,插入null代替最終被過濾OUT(排除)的地方。