gekkio wrote:
I think your criteria query has been defined incorrectly. Here's my explanation:
In this createQuery call you are basically saying that you are going to select a list of TestEntity objects.
Code:
CriteriaQuery<TestEntity> q = builder.createQuery(TestEntity.class);
However, in this line you are selecting the id, not the object (and you are also specifying <TestEntity> with generics here which is incorrect):
Code:
q.select(r.<TestEntity>get("id"));
The first exception is thrown because you are selecting the "id" attribute but you have specified that the results will be TestEntity objects.
The second exception is thrown because you are selecting the "id" attribute and trying to join id.embeddedAttribute which of course doesn't exist.
So, the fix should be pretty simple. Use this instead:
Code:
q.select(r);
it doesn't matter what you select (and should not because what is selected has nothing to do with what is restricted). you can see it for yourself as it works
both ways: with select(r) and with select(r.get("id")).
the problem i experience is that hibernate seems not to allow to join on embedded entities, while JSR clearly says that it should ;).
the fix for this problem is when you need to join on an embedded entity, you must do a "get" instead of "join", which is absolutely not convenient:
Code:
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<TestEntity> q = builder.createQuery(TestEntity.class);
Root<TestEntity> r = q.from(TestEntity.class);
q.select(r.<TestEntity>get("id"));
q.where(builder.equal(r.get("embeddedAttribute").get("enumeratedAttribute"), TestEnum.ONE));
em.createQuery(q).getResultList();
gekkio wrote:
I suggest using the canonical metamodel which solves most type safety issues. In your queries the metamodel would enable you to replace the "magical" string values "id", "embeddedAttribute" and "enumeratedAttribute" with type-safe references.
i can't use metamodel, because i need to be able to address attributes without knowing which attribute this actually is.