Kalich
Kalich

Reputation: 117

Type specified for TypedQuery is incompatible, but Hibernate returns another type

I'm using Hibernate, I have 2 entities, A and B, they are mapped as ManyToMany, A has a Set<B> (I will call this field as set_of_b) and B has a List<A>, and I want to get all B, which contains A with required property (some_a_property), so if I were to make a SQL it would look like this

SELECT b.id, b.first_property, b.second_property
FROM a
JOIN a_b_jointable
ON a.id = a_b_jointable.a_id
JOIN b
ON a_b_jointable.b_id = b.id
WHERE some_a_property = 'value'

In the HQL I firstly tried to do this like this:

Set<B> result = session.createQuery("select set_of_b from A where some_a_property = :value", B.class)
            .setParameter("some_a_property", value)
            .getResultStream()
            .collect(Collectors.toSet());

but I got an error Type specified for TypedQuery [com.example.entities.B] is incompatible with query return type [interface java.util.Set], after that I changed my query to this, to see what will happen:

var result = session.createQuery("select set_of_b from A where some_a_property = :value", Set.class)
            .setParameter("some_a_property", value)
            .getResultStream()
            .collect(Collectors.toSet());

And it worked, but... It returned a HashSet<B>, just as I wanted, not a Set<Set> or whatever. I'm a bit confused by such behavior and I can't figure out, what is happening? Why does it say that the return type is Set, when it actually returns B?

Right now I'm making my queries like this and it works fine:

Set<B> result = session.createQuery("select set_of_b from A where some_a_property = :value", Object.class)
                .setParameter("some_a_property", value)
                .getResultStream()
                .map(x -> (B) x)
                .collect(Collectors.toSet());

Upvotes: 0

Views: 1093

Answers (1)

Christian Beikov
Christian Beikov

Reputation: 16430

It is this way because set_of_b is a Set<B>. What you want can be done by joining the set:

var result = session.createQuery("select b from A a join a.set_of_b b where a.some_a_property = :value", B.class)
        .setParameter("some_a_property", value)
        .getResultStream()
        .collect(Collectors.toSet());

Upvotes: 1

Related Questions