es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Hibernate lazy fetching Hibernate recuperación perezosa

Tengo 3 entidades, por ejemplo Categoría, SubCategoría y Curso.
Una categoría puede tener muchas subcategorías y una subcategoría puede tener muchos cursos.
He creado relaciones de uno a muchos entre categoría-subcategoría y subcategoría-curso utilizando Fetch.Lazy.

class Category {
    @OneToMany(mappedBy = "category")
    private Set<SubCategory> subCategories = new HashSet<>();
}

<p>class SubCategory {
    @ManyToOne
    private Category category;</p>

<pre><code>@OneToMany(mappedBy = "subCategory")
private Set<Course> courses = new HashSet<>();
</code></pre>

<p>}</p>

<p>class Course {
    @ManyToOne
    private SubCategory subCategory;
}</p>

<p>@Service
class CategoryService {
    @PersistenceContext
    private EntityManager entityManager;</p>

<pre><code>public List<Category> findAll() {
    TypedQuery<Category> query =
        entityManager.createQuery("select c from Category c join fetch c.subCategories", Category.class);
    return query.getResultList();
}
</code></pre>

<p>}</p>

<p>@RestController
@RequestMapping
class CategoryController {
    @Autowired
    private CategoryService categoryService;</p>

<pre><code>@GetMapping
public List<Category> findAll() {
    return categoryService.findAll();
}
</code></pre>

<p>}

Ahora, cuando lanzo una consulta de obtener todas las categorías con una unión de subcategorías, obtengo las categorías con las subcategorías unidas en el servicio, pero una vez que se va a dar la salida, se están lanzando ‘n’ pequeñas consultas para obtener los cursos y dármelos como salida, pero no los necesito. ¿Cómo solucionarlo?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para solucionar este problema, podemos hacer uso de la anotación @JsonIgnoreProperties proporcionada por Spring para ignorar ciertas propiedades durante la serialización. En nuestro caso, podemos ignorar la propiedad courses en la entidad SubCategory.

    Para implementar esto, podemos agregar la anotación @JsonIgnoreProperties("courses") a la entidad SubCategory de la siguiente manera:

    class SubCategory {
        ...
    
        @JsonIgnoreProperties("courses")
        @OneToMany(mappedBy = "subCategory")
        private Set<course> courses = new HashSet<>();
    }
    

    Esto asegurará que durante la serialización, la propiedad courses se ignore y no se obtenga de la base de datos, resolviendo así nuestro problema de consultas innecesarias.

    Como alternativa, también podemos utilizar proyecciones en Spring Data JPA para obtener solo las propiedades requeridas de la base de datos. Esto se puede lograr creando una interfaz de proyección que defina las propiedades que necesitamos y luego usándola en la consulta. Por ejemplo, podemos crear una interfaz de proyección para la entidad Category de la siguiente manera:

    public interface CategoryProjection {
        Long getId();
        String getName();
        Set<subcategoryprojection> getSubCategories();
    }
    
    public interface SubCategoryProjection {
        Long getId();
        String getName();
    }
    

    Luego podemos modificar nuestro CategoryService para usar esta proyección en la consulta de la siguiente manera:

    @Service
    class CategoryService {
        @Autowired
        private CategoryRepository categoryRepository;
    
        public List<categoryprojection> findAll() {
            return categoryRepository.findAllProjectedBy();
        }
    }
    

    Esto obtendrá solo las propiedades requeridas de la base de datos y evitará consultas innecesarias para la propiedad courses.

Comments are closed.