I'm trying to fetch Entity1
by querying on mapped entities to it. I'm using CriteriaBuilder
to perform this as shown below
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Entity1> createQuery = criteriaBuilder.createQuery(Entity1.class);
Root<Entity1> root = createQuery.from(Entity1.class);
Join<Entity1, MappedEntity2> mappedEntity2Join = root.join("mappedEntity2");
createQuery.select(root);
predicate = criteriaBuilder.and(predicate, criteriaBuilder.equal(root.get(COL_USER_ID), userId));
// where clause to filter by query params
createQuery.where(predicate).distinct(true);
createQuery.getRestriction();
TypedQuery<Entity1> query = entityManager.createQuery(createQuery);
But In random cases, I found that the query was executed on "Entity2.entities1" without specifying Entity2 in join. My guess is that Entity2 is already available in session and it was lazily initialized with entities1. Because of this Criteria generates a query for Entity2 instead of Entity1.
Is there any way to restrict criteria to query on Entity1? or how to remove the Entity2 from session before executing this particular criteria.
Expected query,
select *
from Entity1 obj1_
inner join mappedEntity1 mObj_ on obj1_.obj_id=mObj_.id
where obj1_.id=?
But the query was generated as,
select *
from entities1_entities2 obj0_
inner join Entity1 obj1_ on obj0_.obj_id=obj1_.id
where obj0_.entity2_id=?
Entities structure:
public class Entity1 {
@ManyToOne
MappedEntity1 mappedEntity1;
@OneToMany
MappedEntity2 mappedEntity2;
@OneToMany
MappedEntity3 mappedEntity3;
}
and
public class Entity2 {
@OneToMany
List<Entity1> entities1;
@OneToOne
MappedEntity2 mappedEntity2;
}
Reference table for Entity1 and Entity2
Table name: entities1_entities2
entity1_id INTEGER NOT NULL,
entity2_id INTEGER NOT NULL,
CONSTRAINT entities1_entities2_entity1_id_fkey FOREIGN KEY (entity1_id)
REFERENCES entity1 (id),
CONSTRAINT entities1_entities2_entity2_id_fkey FOREIGN KEY (entity2_id)
REFERENCES entity2 (id)
I don't think it's random. I'm pretty sure there's something wrong in your mapping.
I can see some thing that don't seem right in your question and you are not showing some information.
The mapping on Entity1 seems wrong, I'm assuming what you mean is:
public class Entity1 {
@ManyToOne
MappedEntity1 mappedEntity1;
@ManyToOne // instead of @OneToMany
MappedEntity2 mappedEntity2;
@ManyToOne // instead of @OneToMany
MappedEntity3 mappedEntity3;
}
And you are not showing the mapping of MappedEntity2
, only the mapping of Entity2
. So I don't know if the bidirectional association is correct.
Even after all this, I think the problem is that you didn't add the mappedBy
attribute to the one-to-many association.
Hibernate is querying entities1_entities2
because you've defined a unidirectional one-to-many in Entity2 and this mapping assumes there is a table called entities1_entities2
mapping the association.
If the association is bidirectional, you need a field in Entity1
like this:
class Entity1 {
@ManyToOne
Entity2 entity2;
...
}
Then you can add the mappedBy
attribute to entities1
in Entity2:
public class Entity2 {
@OneToMany(mappedBy="entity2")
List<Entity1> entities1;
...
}
This will generate the correct query when you join the two entities. Anyway, if you want a better answer you need to improve the question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With