Understanding Hibernate Fetch
I know hibernate has lazy as default fetching strategy, but there are some things unclear to me so i hope you can explain it to me. What i want to do is to get a tile marked as start tile.
Query:
@NamedQuery(name = "Tile.findStartTileByGame",
query = "SELECT t FROM Tile t WHERE t.game = :game " +
"and t.startTile = true and t.blockWalkable = false")
Tile:
public class Tile{
@OneToOne(mappedBy="tile")
private GameCharacter character;
@OneToOne(mappedBy="tile")
private GameObject gameObject;
Game:
@OneToMany(mappedBy="game")
private List<Tile> tiles;
When i run my query and never use the object hibernate still joins me character and gameobject. So i have 3 Queries. I know i can solve this by a fetch join, but my question is why does hibernate fetch both entites at all? Even when i annotate them with fetch=FetchType.LAZY it will be queried.
My DAO:
public static Tile getFreeStartTil开发者_开发百科e(EntityManager em, Game game) {
TypedQuery<Tile> query = em.createNamedQuery("Tile.findStartTileByGame", Tile.class);
query.setParameter("game", game);
List<Tile> result = query.getResultList();
...
Before i fix this i would like to understand why it happens. Thanks in advance m
The reason it happens is that they're marked nullable. When proxying is used, Hibernate still needs to know the difference between ones to proxy and ones that are actually just plain null.
When the relationship is a collection, it can give you an empty collection then check later. But when it's OneToOne
, it has to look in the DB anyway to find out if the field should be null, or if it could be proxied and lazy loaded. Since it has to look anyway, it just loads it.
If you mark both fetch=FetchType.LAZY
and optional=false
you can get lazy fetching on onetoone. Of course if the column actual is nullable, you're SOL.
I found my answer her: http://community.jboss.org/wiki/HibernateFAQ-AdvancedProblems#Hibernate_ignores_my_outerjointrue_or_fetchjoin_setting_and_fetches_an_association_lazily_using_n1_selects
This is also a good question i have missed before which explains it very good: JPA eager fetch does not join
Greetings
精彩评论