5

I have the following scenario (in Java / Hibernate):

  • I have two entity classes: X and Y. X has a @ManyToOne association to Y which is not cascaded.
  • I create an (unmanaged) instance x of X and an (unmanaged) instance y of Y, and fill the reference to y in x. The only field of y that is filled is the primary key.
  • Entity y already has a corresponding row in the underlying database, but entity x is new.
  • I persist entity x.

When I perform this scenario, I expect to see one query: INSERT x. However, what actually happens is that Hibernate performs TWO queries:

  • SELECT y
  • INSERT x

Furthermore, I also notice that after the persist of x, the reference to y does not actually become managed and there is no instance of Y in the session! So, why is the SELECT on y performed at all? Are there ways to prevent this behaviour?

Rubrick
  • 308
  • 5
  • 13

1 Answers1

3

You don't need to (actually you shouldn't) instantiate Y manually. You can do a variant of this (depending on your configuration)

Y y = (Y) session.load(Y.class, pk);

This doesn't retrieve Y from database, instead it loads a proxy consisting only from the pk you mentioned.

Then assigning y to x, and persisting x would behave as you expect.

SelimOber
  • 708
  • 6
  • 17
  • Nice, works like a charm! Any ideas on the other part of my question: in my scenario, why does Hibernate do the SELECT on y? – Rubrick Jul 01 '11 at 09:09
  • I thought about it but didn't have a certain answer. My guess is since you create the instance manually, it's a detached object (not a managed one by hibernate persistence context), so Hibernate needs to check if it really exists in the database. But I'm not sure about it, because even if it didn't exist, the db would throw a foreign key restriction error and the insert would have prevented. In short, I don't know :) – SelimOber Jul 01 '11 at 11:34