Hibernate : HQL로 NULL 쿼리 매개 변수 값을 설정하는 방법은 무엇입니까?
Hibernate 매개 변수를 "null"로 설정하려면 어떻게해야합니까? 예:
Query query = getSession().createQuery("from CountryDTO c where c.status = :status and c.type =:type")
.setParameter("status", status, Hibernate.STRING)
.setParameter("type", type, Hibernate.STRING);
제 경우에는 상태 문자열이 null 일 수 있습니다. 나는 이것을 디버깅하고 최대 절전 모드에서 다음과 같은 SQL 문자열 / 쿼리를 생성합니다 .... status = null
... 그러나 이것은 올바른 SQL 문이 " status is null
" 이어야하므로 MYSQL에서 작동하지 않습니다 (Mysql은 status = null을 이해하지 못하고이를 평가합니다. 내가 읽은 mysql 문서에 따르면 쿼리에 대해 레코드가 반환되지 않도록 false로 설정하십시오.)
내 질문 :
Hibernate
null 문자열을 "is null"로 올바르게 변환하지 않는 이유는 무엇입니까 (그리고 "= null"을 잘못 생성 함)?널 안전하도록이 쿼리를 다시 작성하는 가장 좋은 방법은 무엇입니까? nullsafe를 사용하면 "status"문자열이 null 인 경우 "is null"을 만들어야한다는 의미입니까?
대단히 감사합니다! 팀
최대 절전 모드는 먼저 HQL 쿼리를 SQL로 변환하고 그 후에 만 매개 변수를 바인딩하려고합니다. 즉,에서
param = ?
으로 쿼리를 다시 작성할 수 없습니다param is null
.Criteria API를 사용해보십시오.
Criteria c = session.createCriteria(CountryDTO.class); c.add(Restrictions.eq("type", type)); c.add(status == null ? Restrictions.isNull("status") : Restrictions.eq("status", status)); List result = c.list();
이것은 Hibernate 특정 문제가 아니며 (단지 SQL 특성 임) 예, SQL과 HQL 모두에 대한 솔루션이 있습니다.
@Peter Lang은 올바른 아이디어를 가지고 있었고 올바른 HQL 쿼리를 가지고있었습니다. 나는 당신이 쿼리 변경 사항을 선택하기 위해 새로운 클린 실행이 필요하다고 생각합니다 ;-)
아래 코드는 절대적으로 작동하며 모든 쿼리를 orm.xml에 보관하면 좋습니다.
from CountryDTO c where ((:status is null and c.status is null) or c.status = :status) and c.type =:type
매개 변수 String이 null이면 쿼리는 행의 상태도 null인지 확인합니다. 그렇지 않으면 등호와 비교합니다.
메모:
문제는 특정 MySql 특성 일 수 있습니다. Oracle에서만 테스트했습니다.
위 쿼리는 c.status가 null 인 테이블 행이 있다고 가정합니다.
매개 변수가 먼저 확인되도록 where 절의 우선 순위가 지정됩니다.
매개 변수 이름 'type'은 SQL에서 예약어 일 수 있지만 쿼리가 실행되기 전에 대체되기 때문에 중요하지 않습니다.
: status where_clause를 모두 건너 뛰어야하는 경우; 다음과 같이 코딩 할 수 있습니다.
from CountryDTO c where (:status is null or c.status = :status) and c.type =:type
다음과 동일합니다.
sql.append(" where ");
if(status != null){
sql.append(" c.status = :status and ");
}
sql.append(" c.type =:type ");
에 대한 javadoc에서는setParameter(String, Object)
개체 값이 null이 아닌해야한다는 명시 적입니다. 그러나 null이 전달되면 예외가 발생하지 않는 것이 부끄러운 일입니다.
대안은 setParameter(String, Object, Type)
있는 않는 내가하지 않도록 무엇을 해요하지만, 널 (null) 값을 허용 Type
매개 변수가 가장 적절한 여기에있을 것이다.
is null
HQL에서 사용해야하는 것처럼 보이지만 (널 전위가있는 매개 변수가 둘 이상인 경우 복잡한 순열로 이어질 수 있습니다.) 가능한 해결책은 다음과 같습니다.
String statusTerm = status==null ? "is null" : "= :status";
String typeTerm = type==null ? "is null" : "= :type";
Query query = getSession().createQuery("from CountryDTO c where c.status " + statusTerm + " and c.type " + typeTerm);
if(status!=null){
query.setParameter("status", status, Hibernate.STRING)
}
if(type!=null){
query.setParameter("type", type, Hibernate.STRING)
}
나는 이것을 시도하지 않았지만 :status
두 번 사용 하여 확인 하면 어떻게됩니까 NULL
?
Query query = getSession().createQuery(
"from CountryDTO c where ( c.status = :status OR ( c.status IS NULL AND :status IS NULL ) ) and c.type =:type"
)
.setParameter("status", status, Hibernate.STRING)
.setParameter("type", type, Hibernate.STRING);
HQL은 coalesce를 지원 하여 다음과 같은 추악한 해결 방법을 허용합니다.
where coalesce(c.status, 'no-status') = coalesce(:status, 'no-status')
실제 HQL 쿼리의 경우 :
FROM Users WHERE Name IS NULL
당신이 사용할 수있는
Restrictions.eqOrIsNull("status", status)
대신해서
status == null ? Restrictions.isNull("status") : Restrictions.eq("status", status)
다음은 Hibernate 4.1.9에서 찾은 솔루션입니다. 때때로 NULL 값을 가질 수있는 매개 변수를 쿼리에 전달해야했습니다. 그래서 나는 다음을 사용하여 통과했습니다.
setParameter("orderItemId", orderItemId, new LongType())
그 후 쿼리에서 다음 where 절을 사용합니다.
where ((:orderItemId is null) OR (orderItem.id != :orderItemId))
As you can see, I am using the Query.setParameter(String, Object, Type) method, where I couldn't use the Hibernate.LONG that I found in the documentation (probably that was on older versions). For a full set of options of type parameter, check the list of implementation class of org.hibernate.type.Type interface.
Hope this helps!
this seems to work as wel ->
@Override
public List<SomeObject> findAllForThisSpecificThing(String thing) {
final Query query = entityManager.createQuery(
"from " + getDomain().getSimpleName() + " t where t.thing = " + ((thing == null) ? " null" : " :thing"));
if (thing != null) {
query.setParameter("thing", thing);
}
return query.getResultList();
}
Btw, I'm pretty new at this, so if for any reason this isn't a good idea, let me know. Thanks.
ReferenceURL : https://stackoverflow.com/questions/2123438/hibernate-how-to-set-null-query-parameter-value-with-hql
'IT story' 카테고리의 다른 글
불투명 한 응답에는 어떤 제한이 적용됩니까? (0) | 2020.12.30 |
---|---|
Python에서 렉싱, 토큰 화 및 구문 분석을위한 리소스 (0) | 2020.12.30 |
.net에서 유형 안전이란 무엇입니까? (0) | 2020.12.30 |
C # 정적 클래스 확장 메서드가 지원되지 않는 이유는 무엇입니까? (0) | 2020.12.30 |
PHP 함수의 코드 재구성 / 가져 오기 (0) | 2020.12.30 |