14-mayo-2017
admin

@ElementCollection vs @OneToMany

Estas dos anotaciones nos permiten elaborar relaciones 1 a N entre dos objetos con JPA. A continuación se va a exponer su funcionamiento:

@ElementCollection
Te permite de una forma muy simple definir una relación de una entidad con otros objetos. Se puede por ejemplo, dado un empleado, definir una lista de strings que se corresponden con los telefonos del empleado. Sería así:

@Entity(name="Employee")
@Table(name="EMPLOYEE")
public class Employee {

	@Id
	@Column(name = "_id")
	private String id;

	@Column(name="name")
	private String name;

	@ElementCollection
	@CollectionTable(name="PHONE", joinColumns=@JoinColumn(name="phone_id"))
	@Column(name="phone_number")
	private List< String> phones;
        .....
}

Teniendo en cuenta este ejemplo tendremos en BD:
– Una tabla EMPLOYEE con las columnas -> _id y name.
– Una tabla PHONE con las columnas -> phone_id y phone_number. (el campo phone_id hara de foreign key, mientras que phone_number contendrá el String del número de teléfono)

En el ejemplo anterior usábamos una lista de String pero podríamos usar un objeto @Embeddable, tal que así:

@Entity
public class Employee {
	@Id
	@Column(name = "_id")
	private String id;

	@Column(name="name")
	private String name;

	@ElementCollection
	@CollectionTable(name="PHONE",joinColumns=@JoinColumn(name="phone_id"))
        private List< Phone> phones;
        ...
}

@Embeddable
public class Phone {
        @Column(name="phone_number")
        private String number;
        ...
}

El resultado de hacerlo así en la base de datos sería exactamente el mismo pero nos va a permitir añadir mas campos en el objeto PHONE.

@OneToMany
Te permite relacionar dos objetos Entity.

@Entity
public class Employee {
	@Id
	@Column(name = "_id")
	private String id;

	@Column(name="name")
	private String name;

	@OneToMany(cascade={CascadeType.ALL}, mappedBy="empl", 
                   fetch=FetchType.LAZY, targetEntity = Phone.class)
	@OnDelete(action = OnDeleteAction.CASCADE)
	private List< Phone> phones;
  ...
}

@Entity
public class Phone {
	@Id
	private long id;

	@Column(name="phone_number")
	private String number;

	@ManyToOne
	@JoinColumn(name="phone_id")
	private Employee empl;
	...
}

Como se puede ver hay que marcar la relacion OneToMany en la entidad Employee, marcándole el campo donde debe apuntar (en este caso «empl»). En ese campo de la entidad Phone se debe marcar la ManyToOne indicandole el nombre de la columna (phone_id) que hará de foreign key.

Además, se ha añadido la anotación @OnDelete para indicarle que haga un borrado en cascada de la lista de teléfonos al eliminar al empleado. Esto es significativo por el hecho de que en el caso del ElementCollection no se permite indicar el tipo de borrado.
Nota: Hay que decir que en el borrado en cascada se eliminan de golpe todos los relacionados mientras que sin él, va haciendo un borrado de cada uno de sus relacionados (es decir, si un empleado tiene 10 teléfonos al hacerlo en cascada se lanzaría un único delete mientras que en el otro caso se lanzan 10 sentencias delete).

Resumen final
BD: el esquema de tablas y relaciones que va a construir JPA en nuestra BD va a ser muy similar en ambos casos.
Código: Se puede decir que es mucho más cómodo utilizar @ElementCollection al simplificar el código.
Potencia: Si queremos poder utilizar toda la potencia de las relaciones optimizando nuestros recursos es mejor decantarse por @OneToMany.


Fuente
@ElementCollection
@OneToMany

Comentarios cerrados.

Categorias

Linkedin