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.

Spring RepositoryEventHandler para la modificación de enlaces falta una referencia al destino del enlace.

Estoy utilizando un RepositoryRestController para exponer un punto de enlace REST para modificar la entidad X, la cual está vinculada a otra entidad Y.

class X {
    Set<y> y_set;
}

Me gustaría ejecutar código cuando se agreguen o eliminen los elementos Y de un X.

class MyAction {
    // inicializado de alguna forma
    XRepository xRepo;

    public void unlinkYFromX() {
        X x = xRepo.getAnX();
        // Obtener un Y de los que están vinculados a X utilizando alguna lógica
        Y y = x.getYs().get(0);
        x.getYs().delete(y);
        xRepo.save(x);
        // Espero que los controladores de eventos se activen ahora
        // Dándome una referencia a x e y
    }
}

Estoy intentando definir un RepositoryEventHandler con una función controladora anotada con HandleBeforeLinkSave:

@RepositoryEventHandler
class XYLinkHandler {
    @HandleBeforeLinkSave
    public void handleYLinkSave(X x, Object linked) {
        // Hacer algo de código con la fuente X
        // Y el objeto Y recién vinculado
    }
}

El problema es que el segundo argumento de la función controladora siempre es nulo. En otras palabras, no contiene el objeto Y al que estoy vinculando.

El mismo fenómeno (referencia vinculada que falta) ocurre independientemente de si es un controlador de eventos Antes, Después, Guardar o Eliminar.

¿Alguien ha encontrado este problema?
¿Alguien tiene una solución o una solución alternativa?

Gracias.

Tags:  ,

Answer

  1. Avatar for davy.ai

    Hasta donde yo sé, el evento HandleBeforeLinkSave en RepositoryEventHandler se utiliza para interceptar la creación del enlace entre dos entidades. Sin embargo, en tu caso, estás intentando interceptar la adición o eliminación de una entidad enlazada.

    Una posible solución alternativa es crear un método personalizado en tu interfaz XRepository que encapsule la lógica de agregar o eliminar una entidad Y de X, y luego llamar a este método en lugar de manipular directamente el campo y_set de X.

    Por ejemplo:

    @RepositoryRestResource
    public interface XRepository extends JpaRepository<x, long=""> {
    
        // Método personalizado para agregar o eliminar un Y de X
        @Modifying
        @Query("update X x set x.y_set = :ys where x.id = :xId")
        void updateYs(@Param("xId") Long xId, @Param("ys") Set<y> ys);
    
    }
    

    Luego, en tu clase MyAction, puedes llamar al método updateYs en lugar de eliminar directamente un Y de x.getYs():

    class MyAction {
        // inicializado de alguna manera
        XRepository xRepo;
    
        public void unlinkYFromX() {
           X x = xRepo.getAnX();
           // obtener un Y de los enlazados a X utilizando alguna lógica
           Y y = x.getYs().iterator().next();
           Set<y> newSet = new HashSet<>(x.getYs());
           newSet.remove(y);
           xRepo.updateYs(x.getId(), newSet);
        }
    }
    

    Finalmente, puedes crear un manejador de eventos @PostUpdate en tu clase XYLinkHandler que se activará cuando se actualice el enlace entre X e Y:

    @RepositoryEventHandler
    class XYLinkHandler {
    
        @PostUpdate
        public void handleYLinkUpdate(X x) {
            // hacer algo de código con el X actualizado
            // y el Y recién enlazado o desenlazado
        }
    }
    

    Ten en cuenta que el parámetro linked en el evento HandleBeforeLinkSave originalmente se utiliza para acceder a la entidad X que está creando el enlace, no a la entidad Y enlazada.</x,>

Comments are closed.