programing

하이버네이트 HQL 결과를 사용하여 타입 안전 경고를 회피하는 방법

projobs 2023. 1. 24. 09:51
반응형

하이버네이트 HQL 결과를 사용하여 타입 안전 경고를 회피하는 방법

예를 들어 다음과 같은 질문이 있습니다.

Query q = sess.createQuery("from Cat cat");
List cats = q.list();

이와 같은 것을 만들려고 하면 다음과 같은 경고가 표시됩니다.

Type safety: The expression of type List needs unchecked conversion to conform to List<Cat>


List<Cat> cats = q.list();

피할 방법이 있을까요?

「」를 사용합니다.@SuppressWarnings곳에서나 하는 어느 곳에서나 것이 .다만, 이 조금 됩니다.q.list().

다음 두 가지 기술을 제안합니다.

캐스트 헬퍼를 쓰다

의 모든 것을 .@SuppressWarnings: 에 into곳 into into :

List<Cat> cats = MyHibernateUtils.listAndCast(q);

...

public static <T> List<T> listAndCast(Query q) {
    @SuppressWarnings("unchecked")
    List list = q.list();
    return list;
}

Eclipse에서 피할 수 없는 문제에 대한 경고 생성 방지

에서 Window > > > > 하고 Eclipse Window > Preferences > Java > Compiler > Errors / Warnings 합니다.Ignore unavoidable generic type problems due to raw APIs

이렇게 하면 위에서 설명한 것과 같이 피할 수 없는 유사한 문제에 대해 불필요한 경고가 꺼집니다.

코멘트:

  • 로 했다.Query결과 대신q.list() 이 는 hibernate를 할 수 , "cheating" 메서드는 어떤 할 수 없기 때문입니다.List일반적으로
  • 해서 방법을 도 있어요..iterate()syslog.

오랜만이지만 저 같은 사람에게 도움이 되었으면 좋겠습니다.

javax.persistence api 문서를 보면 이후 새로운 메서드가 추가된 것을 알 수 있습니다.Java Persistence 2.0 중 ★★★★★★★★★★★★★★★★★★★★★★★.createQuery(String, Class<T>) 결과, 반환하다TypedQuery<T>를 사용할 수 있습니다.TypedQuery네가 한 것처럼Query모든 작전이 안전하다는 작은 차이점을 가지고 있습니다.

smth로 코드를 변경합니다.

Query q = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q.list();

준비 다 됐어

는 용용 we we we we we we we we we@SuppressWarnings("unchecked")또한 대부분의 경우 변수 선언에만 사용하려고 하며 메서드 전체로는 사용하지 않습니다.

public List<Cat> findAll() {
    Query q = sess.createQuery("from Cat cat");
    @SuppressWarnings("unchecked")
    List<Cat> cats = q.list();
    return cats;
}

써보세요.TypedQueryQuery '-어울리다' 이런 식이에요

Query q = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q.list();

사용방법:-

TypedQuery<Cat> q1 = sess.createQuery("from Cat cat", Cat.class);
List<Cat> cats = q1.list();

이 코드에서는, 다음과 같이 콜 메서드에 주석을 붙입니다.

@Suppress Warnings ('체크 해제')

해킹처럼 보이는 건 알지만, 공동 개발자가 최근에 확인해보니 그게 우리가 할 수 있는 전부였어요.

Hibernate API의 Query.list() 메서드는 "설계상" 타입이 아니며 변경할 계획은 없습니다.

컴파일러의 경고를 피하기 위한 가장 간단한 해결책은 실제로 @Suppress Warnings("체크되지 않음")를 추가하는 것이라고 생각합니다.주석은 메서드레벨에 배치하거나 메서드 내에 있는 경우에는 변수 선언 바로 앞에 배치할 수 있습니다.

Query.list()를 캡슐화하고 List(또는 Collection)를 반환하는 메서드가 있는 경우에도 경고가 표시됩니다.다만, 이것은 @Suppress Warnings("rawtypes")를 사용해 억제됩니다.

Matt Quail이 제안한listAndCast(Query) 메서드는 Query.list()보다 유연성이 떨어집니다.가능한 한:

Query q = sess.createQuery("from Cat cat");
ArrayList cats = q.list();

아래 코드를 시험해 보면:

Query q = sess.createQuery("from Cat cat");
ArrayList<Cat> cats = MyHibernateUtils.listAndCast(q);

컴파일 에러가 표시됩니다.유형 불일치: 목록에서 ArrayList로 변환할 수 없습니다.

이건 실수나 실수가 아니에요이 경고는 진짜 근본적인 문제를 반영하고 있습니다.Java 컴파일러가 휴지 상태 클래스가 올바르게 동작할 수 있는지, 반환되는 목록에는 Cats만 포함되어 있는지 확인할 수 있는 방법은 없습니다.여기 있는 어떤 제안이라도 좋습니다.

단, 하려면 , , , , , , , , , , , , , , , 을 사용합니다.@SuppressWarnings("unchecked")석입니니다다

의 새로운 은, safe 를 .Query<T> 때문에 더 사용하지 .@SuppressWarnings또는 컴파일러의 경고를 없애기 위해 해킹을 구현합니다.Session API에서Session.createQuery safe 을 반환합니다.Query<T> you 다음과 같이 할 수 .을 사용하다

Query<Cat> query = session.createQuery("FROM Cat", Cat.class);
List<Cat> cats = query.list();

쿼리 결과가 Cat을 반환하지 않을 때도 사용할 수 있습니다.

public Integer count() {
    Query<Integer> query = sessionFactory.getCurrentSession().createQuery("SELECT COUNT(id) FROM Cat", Integer.class);
    return query.getSingleResult();
}

또는 부분 선택을 수행하는 경우:

public List<Object[]> String getName() {
    Query<Object[]> query = sessionFactory.getCurrentSession().createQuery("SELECT id, name FROM Cat", Object[].class);
    return query.list();
}

우리도 같은 문제가 있었어.하지만 Hibernate Query and Session으로 다른 주요 문제를 해결해야 했기 때문에 우리에게 큰 문제는 아니었습니다.

구체적으로는:

  1. 트랜잭션을 커밋할 수 있는 시기를 제어합니다.(tx가 "displayed"된 횟수를 계산하고 tx가 "ended"된 경우에만 tx가 시작된 횟수와 동일한 횟수만큼 커밋하려고 했습니다.트랜잭션을 시작해야 하는지 알 수 없는 코드에 유용합니다.tx 를 필요로 하는 코드는, 1 을 「시작」해, 종료합니다).
  2. 퍼포먼스 메트릭 수집
  3. 실제로 어떤 조치가 취해진다는 것을 알 때까지 거래 개시를 늦추는 것.
  4. query.uniqueResult()의 보다 부드러운 동작

델에게 있어서, 다음과 같은 것이 있습니다.

  1. 쿼리를 확장하는 인터페이스(AmplafiQuery)를 만듭니다.
  2. AmplafiQuery를 확장하고 org.hibernate를 랩하는 클래스(AmplafiQueryImpl)를 만듭니다.쿼리
  3. Tx를 반환하는 Txmanager를 만듭니다.
  4. Tx에는 다양한 생성 기능이 있습니다.메서드를 쿼리하고 AmplafiQueryImpl을 반환합니다.

그리고 마지막으로

AmplafiQuery에는 Query.list()의 범용 이니블버전인 "asList()"가 있습니다.AmplafiQuery에는 Query.uniqueResult()의 범용 이니블버전인 "unique()"가 있습니다(예외를 발생시키지 않고 문제를 기록합니다).

이것은 @Suppress Warnings를 피하기 위한 많은 작업입니다.하지만, 말씀드렸다시피, 포장 작업을 해야 할 더 좋은 이유들이 많이 있습니다.

이게 더 오래된 건 알지만 오늘부로 Matt Quails Answer에서 주의할 점이 2개 있습니다.

포인트 1

이것.

List<Cat> cats = Collections.checkedList(Cat.class, q.list());

이 정도일 것 같아

List<Cat> cats = Collections.checkedList(q.list(), Cat.class);

포인트 2

이것부터

List list = q.list();

여기에

List<T> list = q.list();

브라우저에 의해 원래 회신 태그 마커가 제거된 다른 경고가 감소합니다.

이것을 시험해 보세요.

Query q = sess.createQuery("from Cat cat");
List<?> results = q.list();
for (Object obj : results) {
    Cat cat = (Cat) obj;
}

휴지 상태 쿼리에서 유형 안전 경고를 피하는 좋은 해결책은 Tiphero Query와 같은 도구를 사용하여 유형 안전 hql을 구축하는 것입니다.

Cat cat = from(Cat.class);
org.torpedoquery.jpa.Query<Entity> select = select(cat);
List<Cat> cats = select.list(entityManager);
TypedQuery<EntityName> createQuery = entityManager.createQuery("from EntityName", EntityName.class);
List<EntityName> resultList = createQuery.getResultList();

@Suppress Warnings("체크 해제")를 사용하지 않을 경우 다음을 수행할 수 있습니다.

   Query q = sess.createQuery("from Cat cat");
   List<?> results =(List<?>) q.list();
   List<Cat> cats = new ArrayList<Cat>();
   for(Object result:results) {
       Cat cat = (Cat) result;
       cats.add(cat);
    }

참고로, 코드를 낭비하지 않고 @Supress Warning을 사용할 필요가 없도록 이 기능을 제공하는 유틸리티 메서드를 만들었습니다.

언급URL : https://stackoverflow.com/questions/115692/how-to-avoid-type-safety-warnings-with-hibernate-hql-results

반응형