Is it necessary to fetch an entity in order to reference it, using JPA and MySQL?
foreign-keys, java, jpa, mysql
Solution
You can get a "reference" instance using EntityManager's `getReference()` method rather than loading the entity using find(). These references are lazily fetched, so in your case there would be no need to fetch them at all.
Your code would look similar:
A a = entityManager.getReference(A.class, knownIdForA);
B b = entityManager.getReference(B.class, knownIdForB);
X x = new X();
x.setA(a);
x.setB(b);
entityManager.persist(x);
but only the persist() call would access your DB.
Problem
I'm having an application that creates lots of rows which reference two other entities, i.e. there are two foreign key references in the row which realize ManyToOne relationships. These are the two entities being referenced: ``` CREATE TABLE a ( `id` INT NOT NULL auto_increment, -- lots of other attributes, PRIMARY KEY (id) ) CREATE TABLE b ( `id` INT NOT NULL auto_increment, -- lots of other attributes, PRIMARY KEY (id) ) ``` This is the entity which references a and b: ``` CREATE TABLE x ( `id` INT NOT NULL auto_increment, `f_a` INT NOT NULL, `f_b` INT NOT NULL, CONSTRAINT `FK_a` FOREIGN KEY (`f_a`) REFERENCES `a` (`id`), CONSTRAINT `FK_b` FOREIGN KEY (`f_b`) REFERENCES `b` (`id`), ) ``` a, b, and x are mapped to the classes A, B, and X using JPA via EclipseLink, it's pretty basic and there is nothing fancy about it. When I create an X in Java I do the following (note that a and b already exist and I do know their IDs only - they are feeded from a legacy application): ``` A a = entityManager.find(A.class, knownIdForA); B b = entityManager.find(B.class, knownIdForB); X x = new X(); x.setA(a); x.setB(b); entityManager.persist(x); ``` The thing is I have to insert about 200,000 entities, which is quite a lot. There are about 3 times as many As and Bs respectively, so I have to fetch 200,000 times an A and a B, most likely 200,000 different A and B, so there's not much I can do with caching. My question is: Is it really necessary to fetch the whole entity? Is there a way to reduce these costs? Or is there some way that I can manually set the foreign key reference (which boils down to an integer) without losing the benefits of JPA (i.e. not having to write my own query)? An alternative formulation of the question: How do I accomplish the following with JPA? ``` INSERT INTO x (`f_a`, `f_b`) VALUES (13, 17); ``` where f_a and f_b are foreign keys?