2016-08-31 2 views
0

내 응용 프로그램은 PostgreSQL 9.5 데이터베이스와 함께 최대 절전 모드 5.02와 Wildfly 10을 사용합니다. NamedQuery를 통해 생성 된 엔티티 내에서 보유 된 @OneToMany 컬렉션에서 필터를 사용하려고합니다. 불행히도 마치 필터가 무시되는 것처럼 보입니다. 여기에는 읽기 쉽도록 수정 된 여러 구성 요소가 있습니다. Hibernate 필터가 무시 ​​됨

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



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

@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; 
, 나는 또한 createNativeQuery 대신 getNamedQuery과 행운을 통해 AnalystProcessEntity 클래스를 건설에 필터를 시도했다.

하드 코딩 된 값이있는 defaultCondition을 @FilterDef에 추가하여 기본 조건을 실행할지 여부를 확인했습니다.

저는 @Filter를 클래스 정의 위의 엔티티 정의보다 위에 시도했습니다. 나는 조건 참조 엔티티 필드 (변수 이름) 및 테이블 필드 (열 이름)와 같은 소리를내는 블로그 게시물을 보았습니다. 엔티티의 Java 명명 규칙과 Postgres의 테이블 명명 규칙을 고수하려고했기 때문에이 조건에서 참조를 바꾸려고 시도했지만 아무 소용이 없었습니다.

최대 절전 모드에서 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를 사용하면 OUT이 필터링 된 것 대신에 null이 삽입 된 것 같습니다 (제외됨).