Menu

@Depends funciona con relaciones?

2010-05-14
2012-11-26
  • Leonardo Perez

    Leonardo Perez - 2010-05-14

    pues eso, tengo un campo calculado que depende de la selección de Entidad de una propiedad manyToOne. Pero no calcula o da error, el problema parece ser que cuando dispara el calculo los valores de la relación parecen estar vacios.

    El caso puntual es este:
    "LineaFactura" hace referencia a "LineaPedido"
    cuando se modifica el LineaPedido, LineaFacturadebe recalcular el costo unitario y el total.

    @Depends("lineaPedido")
    @Transient @Stereotype("BOLD_LABEL")
    public float getTransientImporteUnitario() {
            if (getLineaPedido()!=null)
                return getLineaPedido().getImporteTotal() / getLineaPedido().getCantidad();

            return 0.0f;
        }

    es posible que no este cargando todos los campos o de alguna forma la entidad elegida no esté siendo inicializada?, si es así, como puedo forzar a que esos campos sean cargados para poder hacer el cálculo?

    Gracias de antemano,
    Leonardo

     
  • Javier Paniza

    Javier Paniza - 2010-05-17

    Hola Leonardo,

    @Depends solo funciona con propiedades, no con referencias. Pero puedes usar propiedades calificadas, así que puedes poner:

    @Depends("lineaPedido.oid")
    

    en lugar de oid pon el nombre de la propiedad @Id de LineaPedido.


    Aprende OpenXava con ejemplos: Consigue el libro

     
  • Leonardo Perez

    Leonardo Perez - 2010-05-18

    Creí que de esa manera el calculo sería notificado si el ID del objeto referencia cambia… pero aún así no me funciona

    @Depends("this.lineaPedido.id")
        @Transient @Stereotype("BOLD_LABEL")
        public float getTransientImporteUnitario() {
            float unitario = lineaPedido.getImporteTotal() / lineaPedido.getCantidad();
            setImporteUnitario(unitario);
            return unitario;
        }

    el "depends" de descriptionsList funciona de la misma manera? me tira un error cuando habilito este depends:

    @ManyToOne @DescriptionsList(descriptionProperties="pedido.nombre")
        private Factura factura;

    @ManyToOne(optional=false)
    @DescriptionsList(descriptionProperties="cantidad,nombreProducto,importeTotal"),
             depends="this.factura.pedido.id", condition="${pedido.id} = ?")

        private LineaPedido lineaPedido;

    17/05/2010 21:50:13 org.openxava.tab.impl.TableModelBean getRow
    FINA: nextChunk=0
    17/05/2010 21:50:23 org.directwebremoting.util.CommonsLoggingOutput info
    INFO: Exec: Module.request()
    17/05/2010 21:50:23 org.openxava.util.Labels get
    ADVERTENCIA: Imposible internacionalizar elemento con id lineaPedido
    17/05/2010 21:50:23 org.openxava.util.Labels get
    ADVERTENCIA: Imposible internacionalizar elemento con id lineaPedido
    17/05/2010 21:50:23 org.openxava.util.Labels get
    ADVERTENCIA: Imposible internacionalizar elemento con id lineaPedido
    17/05/2010 21:50:23 org.openxava.controller.ModuleManager execute
    FINA: Execute Collection.new=15 ms
    17/05/2010 21:50:23 org.openxava.util.Labels get
    ADVERTENCIA: Imposible internacionalizar elemento con id LineaFactura
    17/05/2010 21:50:23 org.openxava.util.Labels get
    ADVERTENCIA: Imposible internacionalizar elemento con id lineaPedido
    17/05/2010 21:50:23 org.openxava.web.dwr.Module request
    GRAVE: org.openxava.util.ElementNotFoundException: La subvista factura no existe en la vista de Factura.LineaFactura. Intenta usar this.factura
    org.apache.jasper.JasperException: org.openxava.util.ElementNotFoundException: La subvista factura no existe en la vista de Factura.LineaFactura. Intenta usar this.factura
    at org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:522)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:416)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:551)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:488)
    at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968)
    at org.apache.jsp.xava.reference_jsp._jspService(reference_jsp.java:425)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:551)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:488)
    at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968)
    at org.apache.jsp.xava.detail_jsp._jspService(detail_jsp.java:304)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:551)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:488)
    at org.apache.jasper.runtime.JspRuntimeLibrary.include(JspRuntimeLibrary.java:968)
    at org.apache.jsp.xava.core_jsp._jspService(core_jsp.java:246)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
    at org.openxava.web.servlets.Servlets.getURIAsString(Servlets.java:120)
    at org.openxava.web.servlets.Servlets.getURIAsString(Servlets.java:99)
    at org.openxava.web.dwr.Module.getURIAsString(Module.java:188)
    at org.openxava.web.dwr.Module.fillResult(Module.java:198)
    at org.openxava.web.dwr.Module.request(Module.java:86)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.directwebremoting.impl.ExecuteAjaxFilter.doFilter(ExecuteAjaxFilter.java:34)
    at org.directwebremoting.impl.DefaultRemoter$1.doFilter(DefaultRemoter.java:428)
    at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:431)
    at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:283)
    at org.directwebremoting.servlet.PlainCallHandler.handle(PlainCallHandler.java:52)
    at org.directwebremoting.servlet.UrlProcessor.handle(UrlProcessor.java:101)
    at org.directwebremoting.servlet.DwrServlet.doPost(DwrServlet.java:146)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
    at java.lang.Thread.run(Unknown Source)
    Caused by: org.openxava.util.ElementNotFoundException: La subvista factura no existe en la vista de Factura.LineaFactura. Intenta usar this.factura
    at org.openxava.view.View.getSubview(View.java:656)
    at org.openxava.view.View.getValue(View.java:618)
    at org.openxava.view.View.getValue(View.java:628)
    at org.apache.jsp.xava.editors.descriptionsEditor_jsp._jspService(descriptionsEditor_jsp.java:212)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
    … 78 more

    en cada lugar donde dice "this", también probe sin eso.

     
  • doradito

    doradito - 2010-05-18

    Yo tambien tengo problemas con @Depends y @Hidden explico mi caso
    Se supone que @Hidden oculta una propiedad almenos que sea referenciada directamente, pero de todas formas la incluye en los datos de la vista porque es importante para los calculos

    Tengo una entidad llamada producto

    @Views({
        @View(name="search", members="codigo,descripcion"),
        @View(members="codigo,descripcion; " +
                      "bultosPorPalet, productosPorBulto, precio;" +
                      "movimientos")
    })
    @Entity
    public class Producto extends Identificable{
        @Required
        @Column(length=10,unique=true)
        @LabelFormat(LabelFormatType.SMALL)
        private String codigo;
    
        @Required
        @Column(length=100)
        @LabelFormat(LabelFormatType.SMALL)
        private String descripcion;
    
        @Hidden
        @LabelFormat(LabelFormatType.SMALL)
        private Integer bultosPorPalet;
    
        @Hidden
        @LabelFormat(LabelFormatType.SMALL)
        private Integer productosPorBulto;
    

    Y luego tengo otra entidad que es LineaFactura

    @Entity
    public class LineaMovimientoMercancia extends Identificable {
        private String nLinea;
        @ManyToOne(fetch=FetchType.EAGER)
        @ReferenceView("search")
        @NoFrame
        private Producto producto;
        @LabelFormat(LabelFormatType.SMALL)
        private Integer cantidad;
    @LabelFormat(LabelFormatType.SMALL)
        @Depends("cantidad, producto.productosPorBulto")
        public Integer getBultos() {
            return cantidad / producto.getProductosPorBulto();
        }
    

    pues como en la vista search no aparece productosPorBulto a la hora de usarlo me devuelve un nullpointer al no cargarlo.
    Mi solución ha sido crear una accion que extienda onpropertychangeAction y se la he añadido a los campos que necesito que la lancen cuando cambia y desde esta accion con MapFacade me cargo el producto completo.

    Un saludo.

     
  • Javier Paniza

    Javier Paniza - 2010-05-18

    Hola Leonardo,

    no uses this en el depends. Ponlo así:

    @Depends("lineaPedido.id")
    

    En cuanto a lo del @DescriptionsList el depends sí que puede ser "this.factura.pedido.id", pero para que te funcione, en la vista en la que está la referencia anotada, debe haber una subvista de factura, la cual tengo una subvista para el pedido. Es decir, los depends funcionan solo si los datos están visualizados con esa estructura.


    Aprende OpenXava con ejemplos: Consigue el libro

     
  • Javier Paniza

    Javier Paniza - 2010-05-18

    Hola Doradito,

    Se supone que @Hidden oculta una propiedad almenos que sea referenciada directamente, pero de todas formas la incluye en los datos de la vista porque es importante para los calculos

    No, las propiedades @Hidden no son incluidas si no se visualizan.
    Las propiedades @Hidden no son tenidas en cuanta cuando OX genera un tab o una vista por defecto, es una forma de decir que son propiedades internas (como el id o la version). El efecto es como si el programador hubiera definido una vista con todas las propiedades menos esas. Así que su contenido no está la vista.
    Por otra parte, las propiedades @Id son siempre incluidas, aunque estén anotadas con @Hidden.

    En tu caso, esto:

    @Depends("cantidad, producto.codigo")
    

    ¿no te hubiera servido?


    Aprende OpenXava con ejemplos: Consigue el libro

     
  • Leonardo Perez

    Leonardo Perez - 2010-05-18

    como siempre Javier, gracias por tu rápida respuesta.

    He probado primero sin el "this", pero el problema está igual, actualmente el depends se dispara cuando accedo al Modulo de LineaFactura directamente, pero si agrego una entidad desde Factura no hay caso, inclusive genera varios fallos que creo estarán ligados a la carga parcial de la Entidad, entiendo que es para no cargar gran cantidad de datos en Entidades complejas o con muchos datos, pero no hay alguna forma de simplemente forzar que cierto tipo de entidad se cargue completa cada vez? de manera de poder trabajar sobre el modelo directamente?, actualmente tengo implementadas 1 accion para New, una para Edit, cuando voy a calcular una de las propiedades llamo al entityManager para asegurarme de tener todos los datos de la referencia y no me de cero o null, y aún así, no funciona el 100% de las veces, nisiquiera si uso el entityManager para precargar el objeto de referencia y lo seteo, de alguna forma, OX vuelve a setear la referencia con el objeto básico (con ID, pero sin el resto de los campos).

    Ejemplo, LineaFactura en mi caso tiene 2 campos transient que setean en su calculo el valor de los campos correspondientes persistidos, es decir:
    @Transient @Depends(lineaPedido.id)
    public float getTransientImporteUnitario(){
          float unitario = lineaPedido.getImporteTotal() / lineaPedido.getCantidad();
          setImporteUnitario (unitario); //setea el valor a persistir
          return unitario;
    }
    importeUnitario no está en la vista, pero despues de setearlo, OX lo vuelve a setear a 0. Esto es una dificultad menor ya que se resuelve con un método @PrePersist, es solo para marcar la dificultad, inclusive ese cálculo no se dispara siempre, depende del contexto, si se abre desde el módulo de la entidad directamente o desde la referencia en una collección.

     
  • Javier Paniza

    Javier Paniza - 2010-05-19

    Hola Leonardo,

    hay alguna forma de simplemente forzar que cierto tipo de entidad se cargue completa cada vez
    

    Por defecto OpenXava coge solo los datos visualizados. Obtener todos los datos de la entidad, sus referencias y colecciones de forma recursiva, supondría en muchos casos obtener casi toda la base de datos.
    Siempre tienes la opción de crear tu propia acción de buscar, que obtenga más datos de los visualizados, aunque sería mejor buscar la entidad (con MapFacade.findEntity, por ejemplo) y trabajar sobre ella.

    ese cálculo no se dispara siempre, depende del contexto, si se abre desde el módulo de la entidad directamente o desde la referencia

    Eso no debería ser así si usas "this." como prefijo. Haz una versión reducida de tu proyecto que reproduzca tu caso (con 2 o 3 clases lo más simples posibles) y añade un bug con el código de estas clases y los pasos que he de dar para reproducir el problema.


    Aprende OpenXava con ejemplos: Consigue el libro

     
  • doradito

    doradito - 2010-05-25

    He observado una cosa curiosa, cuando la propiedad que esta anotada con @Depends, no se muestra en la vista, coge todos los valores de todos los campos, mientras que si se muestra faltan aquellos valores que no están en la vista.

    ¿A qué se debe?

    Saludos.

     
  • Javier Paniza

    Javier Paniza - 2010-05-26

    Hola Doradito,

    cuando la propiedad que esta anotada con @Depends, no se muestra en la vista, coge todos los valores de todos los campos, mientras que si se muestra faltan aquellos valores que no están en la vista

    Lo siento, no lo entiendo. Ponme un ejemplo, por favor.


    Aprende OpenXava con ejemplos: Consigue el libro

     

Log in to post a comment.