Soporte de planes de captación de EntityManager

Un FetchPlan es la estrategia que el gestor de entidades utiliza para recuperar los objetos asociados si la aplicación tiene que acceder a las relaciones.

Ejemplo

Supongamos por ejemplo que la aplicación tiene dos entidades: Department (Departamento) y Employee (Empleado). La relación entre la entidad Department y la entidad Employee es una relación bidireccional de uno a muchos: Un departamento tiene muchos empleados y un empleado pertenece a un solo departamento. Ya que la mayor parte de las veces en que se capte la entidad Department es probable que se capten sus empleados, el tipo de captación de esta relación de uno a muchos se define como EAGER.

A continuación se ofrece un fragmento de código de la clase Department.

	@Entity
public class Department {

    @Id
    private String deptId;

    @Basic
    String deptName;

		@OneToMany(fetch = FetchType.EAGER, mappedBy="department", cascade = {CascadeType.PERSIST})
		public Collection<Employee> employees;

}

En un entorno distribuido cuando una aplicación llama a em.find(Department.class, "dept1") para buscar una entidad Department con la clave "dept1", esta operación de búsqueda obtendrá la entidad Department y todas sus relaciones captadas de tipo EAGER. En el caso del fragmento de código anterior, estos son todos los empleados del departamento "dept1".

Antes de WebSphere eXtreme Scale 6.1.0.5, la recuperación de una entidad Department y N entidades Employee incurría en N+1 trayectos cliente-servidor porque el cliente recuperaba una sola entidad por trayecto cliente-servidor. Puede mejorar el rendimiento si recupera estas N+1 entidades en un solo trayecto.

Plan de captación

Un plan de captación se puede utilizar para personalizar cómo captar relaciones EAGER personalizando la profundidad máxima de las relaciones. La profundidad de captación sustituye las relaciones EAGER con una profundidad superior a la especificada por relaciones LAZY. De forma predeterminada, la profundidad de captación es la profundidad de captación máxima. Esto significa que se recuperarán todas las relaciones EAGER de todos los niveles navegables mediante EAGER desde la entidad raíz. Una relación EAGER es navegable mediante EAGER desde una entidad raíz si y sólo si todas las relaciones que se inician desde la entidad raíz a ella están configuradas como captadas mediante EAGER.

En el ejemplo anterior, la entidad Employee es navegable mediante EAGER desde la entidad Department porque la relación Department-Employee está configurada como captada mediante EAGER.

Si la entidad Employee tiene otra relación EAGER con una entidad Address, por ejemplo, entonces la entidad Address también será navegable mediante EAGER desde la entidad Department. Sin embargo, si las relaciones Department-Employee se configuraron como de captación LAZY, entonces la entidad ADDRESS no es navegable mediante EAGER desde la entidad Department porque la relación Department-Employee rompe la cadena de captación EAGER.

Se puede recuperar un objeto FetchPlan desde la instancia de EntityManager. La aplicación puede utilizar el método setMaxFetchDepth para cambiar la profundidad de captación máxima.

Un plan de captación está asociado con una instancia de EntityManager. El plan de captación se aplica a cualquier operación de captación, más concretamente como se indica a continuación.

El objeto FetchPlan es mutable. Una vez cambiado, el valor cambiado se aplicará a las operaciones de captación ejecutadas posteriormente.

Un plan de captación es importante para un despliegue distribuido porque decide si las entidades de relación captadas mediante EAGER se recuperan con la entidad raíz en un solo trayecto cliente-servidor o más de uno.

Continuando con el ejemplo anterior, considere ahora que el plan de captación tiene la profundidad máxima definida como infinita. En este caso, cuando una aplicación llama a em.find(Department.class, "dept1") para encontrar una entidad Department, esta operación de búsqueda obtendrá una entidad Department y N entidades Employee en un solo trayecto cliente-servidor. Sin embargo, para un plan de captación con una profundidad de captación máximo definida como cero, sólo se recuperará del servidor el objeto Department, mientras que las entidades Employee se recuperan del servidor sólo cuando se accede a la colección de empleados del objeto Department.

Planes de captación diferentes

Dispone de varios planes de captación diferentes según sus necesidades, que se explican en las secciones siguientes.

Impacto sobre una cuadrícula distribuida

Importante: Si se ordena una relación, utilizando la anotación o la configuración OrderBy, entonces se considera una relación EAGER aunque se haya configurado como una captación LAZY.

Consideraciones sobre el rendimiento en un entorno distribuido

De forma predeterminada, todas las relaciones navegables mediante EAGER desde la entidad raíz se recuperarán en un solo trayecto cliente-servidor. Esto puede mejorar el rendimiento si se van a utilizar todas las relaciones. Sin embargo, en ciertos escenarios de uso, no se utilizan todas las relaciones navegables mediante EAGER desde la entidad raíz, de modo que incurren tanto en una sobrecarga de tiempo de ejecución como de ancho de banda al recuperar las entidades no utilizadas.

Para estos casos, la aplicación puede definir un número pequeño como profundidad de captación máxima para disminuir la profundidad de las entidades que se deben recuperar realizando todas las relaciones EAGER después de dicha profundidad LAZY. Este valor puede aumentar el rendimiento.

Siguiendo aún más con el ejemplo Department-Employee-Address, de forma predeterminada, se recuperarán todas las entidades Address asociadas con empleados del departamento "dept1" cuando se llame a em.find(Department.class, "dept1"). Si la aplicación no utiliza entidades Address, puede definir la profundidad de captación máxima como 1, de modo que las entidades Address no se recuperarán con la entidad Department.