Hibernate OneToOne mapping executes select statement before insert; not sure why
I configured a simple OneToOne mapping in my entity, but when I persist the object I see a "Select" statement being executed by Hibernate just before the Insert and I don't know why.
@Entity
@Table( name = "USER" )
public class NewUser {
@OneToOne
@JoinColumn(name="user_status_type_id", nullable=false)
private UserStatusType userStatusType;
UserStatusType is just a read-only lookup table, so nothing persists 开发者_JAVA百科in that table when I save User.
User u = new User();
u.setUserStatusType( new UserStatusType(101));
session.persis(u);
But when I persist the User object, the output from Hibernate reads as follows:
Hibernate: select userstatus_.user_status_type_id, userstatus_.user_status_name as user2_3_ from USER_STATUS_TYPE userstatus_ where userstatus_.user_status_type_id=?
Hibernate: insert into USER (created, first_name, last_name, password, user_name, user_status_type_id) values (?, ?, ?, ?, ?, ?)
I don't know if that's normal for Hibernate. I figured since it was a "persist" operation I would only see an Insert statement; not sure of the purpose for the Select.
Is the mapping incorrect?
OK, I was able to get an answer from the Hibernate forums. To prevent the SELECT
before INSERT
, if you are sure the referenced row exists in the database, then use Session.load()
or EntityManager.getReference()
.
User u = new User();
u.setUserStatusType( session.load(UserStatusType.class, new Long(id));
session.persist(u);
The session.load()
method doesn't initially load anything, it just creates a proxy for the object and avoids a hit to the database. Now, if you want to access a member (other than the id field) from the class within the context of the session, then Hibernate will go to the database. In my case I just needed the primary key from the referenced object for the INSERT
, so I avoided the database hit.
精彩评论