2016-08-31 5 views
0

Мое приложение использует Hibernate 5.02 и Wildfly 10 с базой данных PostgreSQL 9.5. Я пытаюсь включить фильтр в коллекции @OneToMany, хранящейся внутри объекта, который создается через NamedQuery. К сожалению, кажется, что фильтр просто игнорируется. Здесь представлены различные компоненты, отредактированные для удобства чтения.Hibernate Filter игнорируется

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

Как видно из вышесказанного, я также попробовал фильтр построения класса AnalystProcessEntity через createNativeQuery вместо getNamedQuery и не повезло.

Я также добавил значение по умолчанию с жестко заданными значениями в @FilterDef, чтобы увидеть, будет ли он выполнять условие по умолчанию, и он все еще не сделал этого.

Я пробовал @Filter над определением сущности, а также над определением класса. Я даже наткнулся на сообщение в блоге, в котором он звучал так, как условие ссылается на сущности полей (имена переменных), а не на таблицы (имена столбцов). Попытка придерживаться соглашений о присвоении имен Java в соглашениях об именах Entity и Postgres в таблице, поэтому я попытался переключить ссылки в состоянии и безрезультатно.

У меня есть запись в sql включена в Hibernate, и условие не появляется нигде, как будто это просто игнорируется.

Любая помощь была бы принята с благодарностью!

ответ

0

Итак, проблема заключалась в том, что я применил @FilterDef к неправильному классу. Предполагалось, что, поскольку я создавал AnalystProcessEntity, который содержит коллекцию MsgEntity (которую я пытаюсь фильтровать), что @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 нулевые значения вставлены вместо того, что в итоге было отфильтровано OUT (исключено).

Смежные вопросы