relaciones onetomany one manytoone many ejemplos ejemplo column hibernate jpa orm eclipselink openjpa

hibernate - onetomany - ¿A qué se hace referencia para utilizar el nombre de columna en JPA?



many to one jpa (5)

En JPA hay un atributo llamado referencedColumnName que se puede configurar en @JoinColumn, @PrimaryKeyJoinColumn cuál es la idea detrás de esta configuración, alguien puede dar un buen ejemplo de dónde se puede utilizar?


Citando API en referenciaColumnName :

El nombre de la columna a la que hace referencia esta columna de clave externa.

Predeterminado (solo se aplica si se está utilizando una sola columna de unión): el mismo nombre que la columna de la clave principal de la tabla a la que se hace referencia.

Q / A

¿Dónde se usaría esto?

Cuando hay una PK compuesta en la tabla a la que se hace referencia , debe especificar el nombre de columna al que hace referencia.


Está allí para especificar otra columna como la columna de ID predeterminada de la otra tabla, por ejemplo, considere lo siguiente

TableA id int identity tableb_key varchar TableB id int identity key varchar unique // in class for TableA @JoinColumn(name="tableb_key", referencedColumnName="key")


La propiedad "referencedColumnName" es el nombre de la columna de la tabla que está haciendo referencia con la columna que está anotando. O de manera breve: es la columna a la que se hace referencia en la tabla de destino. Imagine algo como esto: automóviles y personas. Una persona puede tener muchos automóviles, pero un automóvil pertenece solo a una persona (lo siento, no me gusta que nadie más conduzca mi automóvil).

Persona de la mesa
nombre char (64) clave principal
edad int

Coche de tabla
car_registration char (32) clave principal
car_brand (char 64)
car_model (char64)
owner_name char (64) foreign key references Persona (nombre)

Cuando implemente clases tendrá algo como

class Person{ ... } class Car{ ... @ManyToOne @JoinColumn(columnName="owner_name", referencedColumnName="name") private Person owner; }

Espero que esto ayude.



  • name puntos de atributo a la columna que contiene la asociación, es decir, el nombre de la columna de la clave externa
  • referencedColumnName atributo referencedColumnName apunta a la columna relacionada en la entidad asociada / referenciada, es decir, el nombre de columna de la clave primaria

No es necesario que rellene el Address columna referencedColumnName si la entidad a la que se hace referencia tiene una sola columna como PK, porque no hay duda a qué columna hace referencia (es decir, el ID de columna única de Address ).

@ManyToOne @JoinColumn(name="ADDR_ID") public Address getAddress() { return address; }

Sin embargo, si la entidad a la que se hace referencia tiene PK que abarca varias columnas, el orden en el que se especifican @JoinColumn anotaciones @JoinColumn tiene significado. Puede funcionar sin el nombre de columna referencedColumnName especificado, pero eso es solo por suerte. Entonces deberías mapearlo así:

@ManyToOne @JoinColumns({ @JoinColumn(name="ADDR_ID", referencedColumnName="ID"), @JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP") }) public Address getAddress() { return address; }

o en el caso de ManyToMany :

@ManyToMany @JoinTable( name="CUST_ADDR", joinColumns= @JoinColumn(name="CUST_ID"), inverseJoinColumns={ @JoinColumn(name="ADDR_ID", referencedColumnName="ID"), @JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP") } )

Ejemplo de vida real

Dos consultas generadas por Hibernate de la misma asignación de tabla de combinación, ambas sin columna de referencia especificada. Solo se modificó el orden de @JoinColumn anotaciones @JoinColumn .

/* load collection Client.emails */ select emails0_.id_client as id1_18_1_, emails0_.rev as rev18_1_, emails0_.id_email as id3_1_, email1_.id_email as id1_6_0_ from client_email emails0_ inner join email email1_ on emails0_.id_email=email1_.id_email where emails0_.id_client=''2'' and emails0_.rev=''18''

/* load collection Client.emails */ select emails0_.rev as rev18_1_, emails0_.id_client as id2_18_1_, emails0_.id_email as id3_1_, email1_.id_email as id1_6_0_ from client_email emails0_ inner join email email1_ on emails0_.id_email=email1_.id_email where emails0_.rev=''2'' and emails0_.id_client=''18''

Estamos consultando una tabla de unión para obtener los correos electrónicos del cliente. El {2, 18} es una identificación compuesta de Cliente. El orden de los nombres de las columnas está determinado por su orden de anotaciones @JoinColumn . El orden de ambos enteros es siempre el mismo, probablemente ordenado por hibernación y es por eso que se requiere una alineación adecuada con las columnas de la tabla de unión y no podemos o debemos confiar en el orden de mapeo.

Lo interesante es que el orden de los enteros no coincide con el orden en el que están mapeados en la entidad, en ese caso esperaría {18, 2} . Así que parece que Hibernate está ordenando los nombres de las columnas antes de usarlas en la consulta. Si esto es cierto y usted ordenaría su @JoinColumn de la misma manera que no necesitaría referencedColumnName , pero digo esto solo para ilustración.

Los atributos apropiadamente rellenos referencedColumnName dan como resultado exactamente la misma consulta sin la ambigüedad, en mi caso la segunda consulta ( rev = 2 , id_client = 18 ).