Skip to main content

@ViewEntity con Jmoordb-core

 @ViewEntity con Jmoordb-core

Ofrece la posibilidad de crear Vistas de una entidad e incorporarlas dentro de otra entidad, documento embebido o vista mediante el uso de la anotación @ViewEntity se define una vista y se integra mediante el uso de @ViewReferenced.

Las vistas en jmoordb-core permiten realizar operasciones C.R.U.D. y se pueden integrar en otras vistas, entidades y documentos embebidos.



Un ejemplo de documento  almacenado en MongoDB




Mostrare un ejemplo de una referencia sin el uso de vistas.

Declare una clase de tipo @DocumentEmbeddable

@DocumentEmbeddable
public class Profile {
    @Ignore
    private Long id;
     
    @Referenced(from = "applicative", localField = "idapplicative")
    private Applicative applicative;
    @Referenced(from = "role", localField = "idrole")    
    private Role role;
    @Referenced(from = "departament", localField = "iddepartament")
    private Departament departament;
   //set/get
   }
   

Declare la entidad User

@Entity()
public class User {

    @Id(autogeneratedActive = AutogeneratedActive.ON)
    private Long iduser;
    @Column
    private String username;

    @Column
    private String cellphone;
    @Column
    private String email;
    @Column
    private String identificationcard;
    @Column
    private String sex;
    @Column
    private String socialsecuritynumber;
    @Column
    private String name;
    @Column
    private String password;
    @Column
    private String photo;

    @Column
    private Date dateofbirth;

    @Referenced(from = "central", localField = "idcentral")
    private Central central;

    @Embedded
    List<Profile> profile;
    
    @Column
    private Boolean active;


Omitiremos las otras declaraciones de entidades para no hacer muy larga la demostración.


@Entity
public class Departament {

    @Id(autogeneratedActive = AutogeneratedActive.ON)
    private Long iddepartament;
    @Column
    private String departament;
    @Column
    private String shortname;

    @Column
    private Boolean active;

    @Referenced(from = "central", localField = "idcentral")
    private Central central;
    
    // set/get
 }
 
 @Entity
public class Role {

    @Id(autogeneratedActive = AutogeneratedActive.ON)
    private Long idrole;
    @Column
    private Boolean active;

    @Column
    private String role;
    //set/get
    
}


















.


Applicative

@Entity
public class Applicative {
    @Id(autogeneratedActive = AutogeneratedActive.ON)
    private Long idapplicative;
    @Column
    private Boolean active;
    @Column
    private String applicative;
    @Column
    private String description;
    @Column
    private String image;
    @Column
    private String path;
    @Column
    private String shortname;
    @Embedded
    List<Applicativerole> applicativerole;
    @Embedded
    List<Emailconfiguration> emailconfiguration;
    @Embedded
    List<Applicativeprivilege> applicativeprivilege;    
    //set/get    
 }  


 Tenga presente que deberá crear una entidad y un repositorio para cada colección de la base de datos que usamos en el ejemplo.


@Repository(entity = User.class)
public interface UserRepository extends CrudRepository<User, Long> {
    @Find
    public Optional<User> findByUsername(String username); 
    @Lookup
    public List<User> lookup(Search search);
}


Creee un Controller con Eclipse Microprofile.io para consultar la colección User



@Path("user")
public class UserController {

   @Inject
    UserRepository userRepository;
    
    @GET
    @RolesAllowed({"admin"})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
        
    
    public List<User> findAll() {     
        return userRepository.findAll();
    }
    
}

Podemos observar el tamaño que nos devuelve ya que al consultar User , obtiene la lista de documento sembebidos Profile(applicative,(tiene documentos embebidos) ,role(es una entidad siemple),Departamente  (tiene referencia a Central y Central a Institution)). Tambien se procesa la referencia a Central y esta tiene referencia a Instirution.

Como puede observar son muchas referencias internas, que tal vez no necesitamos en nuestra aplicación

Al hacer la consulta, insertando varios documentos con referencias internas podemos obtener una salida como la siguiente.



Obtendríamos un JSON de gran tamaño


@ViewEntity


No necesitamos que se ejecuten consultas sobre referencias internas, ya que deseamos un mejor perfomance de la aplicación y por ejemplo cuando consulto Applicative no deseo obtener todos los elementos, y cuando consulto Departament no necesito que internamente consulte Central ni Institution que son referencias internas.


Cree una vista mediante la anotación   @ViewEntity, observe que solo colocamos algunos atributos omitimos la lista de documentos embebidos
@ViewEntity(collection = "applicative")
public class ApplicativeView {

    @Id(autogeneratedActive = AutogeneratedActive.ON)
    private Long idapplicative;
    @Column
    private Boolean active;

    @Column
    private String applicative;
    @Column
    private String description;

    @Column
    private String image;
    @Column
    private String path;
    @Column

    private String shortname;
    //set/get
    
   }
   

DepartamentView, eliminamos la referencia a Central.
@ViewEntity(collection = "departament")
public class DepartamentView {

    @Id(autogeneratedActive = AutogeneratedActive.ON)
    private Long iddepartament;
    @Column
    private String departament;
    @Column
    private String shortname;

    @Column
    private Boolean active;
    //set/get
    
   }
   


Modifique Profile para que utilice las vistas mediante @ViewReferenced

@DocumentEmbeddable
public class Profile {

    @Ignore
    private Long id;

    @ViewReferenced(from = "applicative", localField = "idapplicative")
    private ApplicativeView applicativeView;
    @Referenced(from = "role", localField = "idrole")
    private Role role;
    @ViewReferenced(from = "departament", localField = "iddepartament")
    private DepartamentView departamentView;

    @Column
    private Boolean active;
    
    //set/get
    
   }

Defina una vista para Central eliminando la referencia a Insitution
@ViewEntity(collection = "central")
public class CentralView {
    @Id
    private Long idcentral;
    @Column
    private String central;
    @Column
    private Boolean active;
    //set/get
    
   }
   
Es necesario definir un Repositorio para cada vista de la misma manera en que lo define para cada Entidad
@Repository(entity = DepartamentView.class,collection = "departament")
public interface DepartamentViewRepository extends CrudRepository<DepartamentView, Long> {
    @Find
    public Optional<DepartamentView> findByDepartament(String departament);
    
    @Lookup
public List<DepartamentView> lookup(Search search);
}
   }
   

Edite User.java y coloque un @ViewReferenced a CentralView

@Entity()
public class User {

    @Id(autogeneratedActive = AutogeneratedActive.ON)
    private Long iduser;
    @Column
    private String username;

    @Column
    private String cellphone;
    @Column
    private String email;
    @Column
    private String identificationcard;
    @Column
    private String sex;
    @Column
    private String socialsecuritynumber;
    @Column
    private String name;
    @Column
    private String password;
    @Column
    private String photo;

    @Column
    private Date dateofbirth;

    @ViewReferenced(from = "central", localField = "idcentral")
    private CentralView centralView;

    @Embedded
    List<Profile> profile;
    
    @Column
    private Boolean active;

   }


Al realizar la consulta puede observar que el tiempo de respuesta es menor y el tamaño del archivo JSON es de 98.19k, comparado con los 261.58kb si usamos referencias.

Conclusiones

  • @ViewEntity permite mejorar los tiempos de respuesta y elimina el llamado a referencias internas en las clases que se implementan.
  • Es fácil de utilizar
  • Necesita diseñar adecuadamente las funcionalidades para aprovechar los beneficios de las mismas.
  • Se esta trabajando en el soporte de  jmoordb-core para la especificación Jakarta NoSQL.


Comments

Popular posts from this blog

Tutorial básico de aplicaciones Web con NetBeans parte 1

NetBeans ofrece un excelente soporte para el desarrollo de aplicaciones Web, en esta ocasión lo haremos utilizando el Framework Java Server Faces 2.0. En el Menu Seleccionamos Nuevo->Proyecto y luego en Categorias Java Web y en tipo de Proyectos Web  Application indicamos el nombre del proyecto Seleccinamos el servidor Web, usamos GlassFish ya que este soporta EJB3.0 y JSF 2.0 Framework Java Server Faces El IDE genera el esquelto del proyecto Web Pages   almacenamos las paginas .html, xhtml, jsf, los archivos de recursos, los scripts .js, imagenes Source Packages    Son las clases Java  Test Packages    Son las clases que usamos para los Test Libraries     Tenemos las bibliotecas de Java y GlassFish necesarias para ejecutar la aplicación Web. Test Libraries     Están las bibliotecas usadas para los test  Configuration Files    Archivos de configuración de la aplicación. Ejecutamos la...

Incrementar Memoria NetBeans

Algunas veces necesitamos incrementar la memoria para un mejor rendimiento. http://www.netbeans.org/community/releases/55/uml-download.html Este es un ejemplo para UML. Descripción en ingles. Increasing Memory Settings (applicable to all builds) The default memory settings for NetBeans should be increased for UML projects. If you have the available memory, Locate your NetBeans installation directory ($install_dir). This can be found by starting up NetBeans and selecting Help -> About then select the Detail tab. Edit the $install_dir/etc/netbeans.conf file. Find the line defining netbeans_default_options . Increase the maximum memory attribute to -J-Xmx512m. If you experience heap overflows while working with larger files, you should increase this value further.

Test con JUnit

El viernes dicte un taller en el que conversábamos sobre Tecnologías Java y luego desarrollamos una aplicación muy básica para demostrar como utilizar JUnit con NetBeans. Pasos: 1. Crear un proyecto Desktop con NetBeans 2. Crear una clase llamada Operaciones 3. Diseñados un formulario y agregramos componentes de manera que quede similar a la figura Código de los botones try { double a = Double.parseDouble(jTextField1.getText()); double b = Double.parseDouble(jTextField2.getText()); Operaciones operaciones = new Operaciones(); double r = operaciones.Sumar(a, b); jTextField3.setText(String.valueOf(r)); } catch (Exception ex) { JOptionPane.showMessageDialog(this, ex.getMessage().toString()); } 4. Creamos los test Seleccionamos las clases En el menu Herramientas,seleccionamos Crear pruebas JUnit Seleccionamos la versión de JUnit En la ventana siguiente seleccionamos los parámetros para nuestras pruebas . Le quitamos la selección a Probar Inicializador y Probar Finalizador NetBeans crea las...