2012-08-27 11 views
5

Tengo una aplicación que crea muchas filas que hacen referencia a otras dos entidades, es decir, hay dos referencias de clave externa en la fila que realizan relaciones ManyToOne.¿Es necesario buscar una entidad para hacer referencia a ella, utilizando JPA y MySQL?

Estas son las dos entidades que se hace referencia:

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) 
) 

Esta es la entidad que hace referencia a y 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, y x se asignan a las clases A, B , y X usando JPA a través de EclipseLink, es bastante básico y no tiene nada de particular.

Cuando creo una X en Java hago lo siguiente (tenga en cuenta que A y B ya existen y que sí sé sus documentos de identidad única - que feeded de una aplicación heredada):

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); 

La cosa es Tengo que insertar aproximadamente 200,000 entidades, lo cual es bastante. Hay aproximadamente 3 veces más As y Bs respectivamente, así que tengo que buscar 200,000 veces una A y una B, muy probablemente 200,000 A y B diferentes, así que no hay mucho que pueda hacer con el almacenamiento en caché.

Mi pregunta es: ¿Es realmente necesario ir a buscar a toda la entidad? ¿Hay alguna manera de reducir estos costos? ¿O hay alguna forma de que pueda establecer manualmente la referencia de la clave externa (que se reduce a un número entero) sin perder los beneficios de JPA (es decir, no tener que escribir mi propia consulta)?

Una formulación alternativa de la pregunta: ¿Cómo logro lo siguiente con JPA?

INSERT INTO x (`f_a`, `f_b`) VALUES (13, 17); 

donde f_a y f_b son claves foráneas?

Respuesta

6

Puede obtener una instancia de "referencia" utilizando el método getReference() de EntityManager en lugar de cargar la entidad utilizando find(). Estas referencias son extraídas de forma perezosa, por lo que en su caso no habría necesidad de buscarlas en absoluto.

Su código será 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); 

pero sólo el persist() llamada sería acceder a su base de datos.

Cuestiones relacionadas