0

I have a java method that returns an Optional<Long>:

Optional<Long> findOptionalRelation(String a, String b)

In the implementation there is a nativeQuery that counts results in a database:

  hqlBuilder.append("SELECT count(r.id)");
  hqlBuilder.append(" FROM RELATION r");
  hqlBuilder.append(" WHERE r.a = :a AND r.b = :b");
  final Query<Long> query = this.getCurrentSession().createNativeQuery(finalQuery);
            query.setParameter("a", a);
            query.setParameter("b", b);
            return query.uniqueResultOptional();

However, when I execute the method test, it returns an Optional<BigInteger> instead of an Optional<Long>.

After that, I did a test for myself with Optional<Long> longOpt = Optional.of(new BigInteger("0")); which of course cannot be cast.

How can I have bypassed the method return without breaking the execution?

Edit: this is the debugger:

Debugger

  • I'm pretty sure there is an overloaded version of `createNativeQuery` with `resultClass` parameter. Did you try it? – Vinh Truong Apr 28 '22 at 15:54
  • Yes, I use `TypedQuery` for that, because when I use that overload version of `createNativeQuery` I get an `org.hibernate.MappingException`, I dont want an entity, I want a `Number` – Rodrigo Doe Apr 29 '22 at 07:31
  • 1
    What is the declaration of `createNativeQuery`? Apparently, it allows you to use an arbitrary type argument without constraints. That’s a fundamental design flaw that easily leads to such problems. But some API designers prefer convenience over correctness. – Holger Apr 29 '22 at 08:18

1 Answers1

2

The reason you didn't get a casting issue at runtime is due to type erasure, you can read about this feature on the docs or in other discussions. This mechanism essentially removes the generic type argument at compilation, meaning that at runtime it is not known.

Fede MG
  • 53
  • 6