I have these entities:
@Entity
public class Room {
@ManyToOne(optional=true,fetch=FetchType.LAZY)
private Player player1;
...
}
@Entity
public class Player {
@Id
@Column(updatable=false)
private long id;
public long getId() {
return id;
}
...
}
Now, this statement inside Room
...
player1.getId();
...will cause that entire Player
entity to be fetched from the database. However, I just need its primary key, id
, which it should already have (otherwise how can it fetch the data?).
How can I access the lazy Player
proxy's id
without triggering database access?
Providing a proxy implementation is an easy and efficient way to use lazy loading in hibernate. A proxy is substituted when hibernating intercepts calls to entity class for it to be derived. For explicit enabling of lazy loading, we use fetch.
The hibernate the last loading is a commonly used design pattern in programming the computer, which contributes to efficiency if perfectly used. Providing a proxy implementation is an easy and efficient way to use lazy loading in hibernate. A proxy is substituted when hibernating intercepts calls to entity class for it to be derived.
The proxy class is a subclass of your entity class and implements the HibernateProxy interface. This enables you to use the proxy object in almost the same way as using the entity object.
Effect of lazy loading on detached entities As we know that hibernate can only access the database via a session, So If an entity is detached from the session and when we try to access an association (via a proxy or collection wrapper) that has not yet been loaded, Hibernate throws a LazyInitializationException.
Hibernate should keep the object's ids linked also to the current Session
. And there is a getIdentifier() method on the Session
that should get the id. The documentation is not saying anything about it, but normally it shouldn't initialize the object.
You could have a attribute of @Column private long playerId
on the Room entity. You could call this attribute to get the id without having to call the entire Player object in the transaction.
This would only work if the playerId was also stored in the Room entity table (or view etc), but I assume it must be as it's needed to be able to make the join in the first place.
edit : as @Adam Dyga mentioned below, these should be insertable and updatable both as false
@Entity
public class Room {
@ManyToOne(optional=true,fetch=FetchType.LAZY)
private Player player1;
@Column(name="id", insertable = false, updatable = false)
private long playerId
...
}
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