Una relación ManyToOne
en Java es aquella en la que el objeto origen tiene un atributo que hace referencia a otro objeto, el objeto destino. Es decir, el caso bastante típico de Java en el que un objeto tiene una referencia a otro objeto. Una relación ManyToOne
puede especificarse de forma unidireccional. Sin embargo, es típico que el objeto de destino tenga la relación inversa especificada de vuelta al objeto de origen. Esto sería una especificación de relación OneToMany
en el objeto destino. Todas las relaciones en Java y JPA son unidireccionales, en el sentido de que si un objeto fuente hace referencia a un objeto destino no hay garantía de que el objeto destino también tenga una relación con el objeto fuente. Esto es diferente a una base de datos relacional, en la que las relaciones se definen a través de claves externas y la consulta de tal manera que la consulta inversa siempre existe.
En JPA una relación ManyToOne
se especifica a través de la anotación @ManyToOne
o el elemento <many-to-one>
. Una anotación @ManyToOne
suele ir acompañada de una anotación @JoinColumn
. La anotación @JoinColumn
especifica cómo debe asignarse la relación a la base de datos (expresada en ella). El @JoinColumn
define el nombre de la columna de clave foránea (@JoinColumn(name = "...")
) en el objeto de origen que debe utilizarse para encontrar (unir) el objeto de destino.
Si se especifica la relación inversa OneToMany
en el objeto de destino, entonces la anotación @OneToMany
en el objeto de destino debe contener un atributo mappedBy
para definir esta relación inversa.
JPA también define una relación OneToOne
, que es similar a una relación ManyToOne
, excepto que la relación inversa (si se definiera) es una relación OneToOne
. La principal diferencia entre una relación OneToOne
y una ManyToOne
en JPA es que una ManyToOne
siempre contiene una clave foránea desde la tabla del objeto origen a la tabla del objeto destino, mientras que en una relación OneToOne
la clave foránea puede estar tanto en la tabla del objeto origen como en la tabla del objeto destino.
- Ejemplo de relación ManyToOne databaseEdit
- Ejemplo de una relación ManyToOne annotationsEdit
- Ejemplo de una relación ManyToOne XMLEdit
- Ver tambiénEdit
- Problemas comunesEditar
- La clave foránea es también parte de la clave primaria.Editar
- La clave foránea también se mapea como básica.Editar
- Error de restricción en la inserción.Editar
- El valor de la clave foránea es nullEdit
Ejemplo de relación ManyToOne databaseEdit
EMPLOYEE (tabla)
EMP_ID | FIRSTNAME | ÚltimoNombre | Salario | Identificación de Gerente |
1 | Bob | Vía | 50000 | 2 |
2 | Sarah | Smith | 75000 | null |
Teléfono (tabla)
ID | TYPE | AREA_CODE | P_NUMBER | OWNER_ID |
1 | home | 613 | 792-0000 | 1 |
2 | trabajo | 613 | 896-1234 | 1 |
3 | trabajo | 416 | 123-4444 | 2 |
Ejemplo de una relación ManyToOne annotationsEdit
@Entitypublic class Phone { @Id private long id; ... // Specifies the PHONE table does not contain an owner column, but // an OWNER_ID column with a foreign key. And creates a join to // lazily fetch the owner @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="OWNER_ID") private Employee owner; ...}// Specification of the reverse OneToMany relationship in Employee@Entitypublic class Employee { @Id private long emp_id; ... // The 'mappedBy = "owner"' attribute specifies that // the 'private Employee owner;' field in Phone owns the // relationship (i.e. contains the foreign key for the query to // find all phones for an employee.) @OneToMany(mappedBy = "owner") private List<Phone> phones; ...
Ejemplo de una relación ManyToOne XMLEdit
<entity name="Phone" class="org.acme.Phone" access="FIELD"> <attributes> <id name="id"/> <many-to-one name="owner" fetch="LAZY"> <join-column name="OWNER_ID"/> </many-to-one> </attributes></entity>
Ver tambiénEdit
- Relaciones
- Cascading
- Lazy Fetching
- Entidad de destino
- Recogida conjunta
- Lectura por lotes
- Problemas comunes
- OneToOne
- Mapping a OneToOne usando una tabla Join
- OneToMany
Problemas comunesEditar
La clave foránea es también parte de la clave primaria.Editar
Ver Claves primarias a través de las relaciones OneToOne.
La clave foránea también se mapea como básica.Editar
Si se utiliza el mismo campo en dos mapeos diferentes, normalmente se requiere hacer uno de ellos de sólo lectura utilizando insertable, updatable = false
. Ver Target Foreign Keys, Primary Key Join Columns, Cascade Primary Keys.
Error de restricción en la inserción.Editar
Esto suele ocurrir porque ha mapeado incorrectamente la clave foránea en una relación OneToOne
.Ver Target Foreign Keys, Primary Key Join Columns, Cascade Primary Keys. También puede ocurrir si su proveedor JPA no soporta la integridad referencial, o no resuelve las restricciones bidireccionales. En este caso usted puede necesitar ya sea para eliminar la restricción, o el uso de EntityManager
flush()
para asegurar el orden de sus objetos se escriben en.
El valor de la clave foránea es nullEdit
Asegúrese de establecer el valor del OneToOne
del objeto, si el OneToOne
es parte de una relación bidireccional OneToMany
, asegúrese de establecer el OneToOne
del objeto al agregar un objeto al OneToMany
, JPA no mantiene las relaciones bidireccionales para usted. También compruebe que definió el JoinColumn
correctamente, asegúrese de que no estableció insertable, updateable = false
o utilizó un PrimaryKeyJoinColumn
.