How to populate a class with PropertyBusinessObject correctly

42 views
Skip to first unread message

rdvg...@gmail.com

unread,
Jul 6, 2019, 1:41:44 PM7/6/19
to CodenameOne Discussions
Hi,
I am using the book created by Mr. Shai as a base to carry out my development and I clarify that I do not know anything about Spring Boot, JPA, Jersey, etc. I am trying to login but I have encountered a problem that for many will be trivial.
On the server I have an entity that represents the users with the following information:

@Entity
public class Usuario {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "usr_usuario_id")
    private Long usuarioId;
    @Column(name = "usr_usuario")
    private String usuario;
    @Column(name = "usr_correo")
    private String correo;
    @Column(name = "usr_contrasena")
    private String contrasena;
    @Column(name = "usr_nombre")
    private String nombre;
    @Column(unique=true, name = "usr_token")
    private String token;
    @JoinColumn(name = "usr_dispositivo_id", referencedColumnName = "dis_dispositivo_id")
    @ManyToOne
    private Dispositivo dispositivoId;
    
// Getting and Setting
    
}

In the client, create the class with the information of the user that implements the PropertyBusinessObject API:

public class Usuario implements PropertyBusinessObject {

    public final LongProperty<Usuario> usuarioId = new LongProperty<>("usuarioId");
    public final Property<String, Usuario> usuario = new Property<>("usuario");
    public final Property<String, Usuario> correo = new Property<>("correo");
    public final Property<String, Usuario> contrasena = new Property<>("contrasena");
    public final Property<String, Usuario> nombre = new Property<>("nombre");
    public final Property<String, Usuario> token = new Property<>("token");

//    public final LongProperty<Usuario> dispositivo = new LongProperty<>("dispositivoId");


    private final PropertyIndex idx = new PropertyIndex(this, "Usuario", usuarioId, usuario, nombre,
            correo, contrasena, dispositivo, tipo, token,  estado);

    @Override
    public PropertyIndex getPropertyIndex() {
        return idx;
    }

The code to do the login in the client is the following:

    public static void login(String usr, String contrasena, final SuccessCallback<Usuario> onSuccess, final FailureCallback<Object> onError) {
        Rest.get(SERVER_URL + "usuario/login").
                acceptJson().
                queryParam("contrasena", contrasena).
                queryParam("usr", usr).
                getAsJsonMapAsync(new Callback<Response<Map>>() {
                    @Override
                    public void onSucess(Response<Map> value) {
                        me = new Usuario();
                        me.getPropertyIndex().populateFromMap(value.getResponseData());

                        Preferences.set("token", me.token.get());
                        PreferencesObject.create(me).bind();

                        onSuccess.onSucess(me);
                    }

                    @Override
                    public void onError(Object sender, Throwable err, int errorCode, String errorMessage) {
                        onError.onError(null, err, errorCode, errorMessage);
                    }
                });
    }

The returned value contains the information of the "User" and the information of the "Devices". How do I receive the information of the "Devices" ?.

Shai Almog

unread,
Jul 6, 2019, 11:27:00 PM7/6/19
to CodenameOne Discussions
Hi,
dispositivoId is commented out in the client side. Did you make the appropriate change to the DAO?

You can use the network monitor to see that the data passes back to the client side.

rdvg...@gmail.com

unread,
Jul 7, 2019, 2:28:33 PM7/7/19
to CodenameOne Discussions
Hi,

Precisely, I do not know how I should change the DAO, I would appreciate a guide.

Thanks

rdvg...@gmail.com

unread,
Jul 7, 2019, 3:09:55 PM7/7/19
to CodenameOne Discussions
Hi,

As far as I can investigate, I have 2 paths:
The first is to make a DTO class on the server that contains all the properties that I need "User" and "Device". Then create a repository to extract the information and this is what I send to the client. The client has a custom class with all the properties of both tables and when executing the method "populateFromMap" all the information is loaded.

The second is to leave the server like this and when sending the information to the client, look for the way that the data of "User" and "Device" load them in a single class "UserDevice".

I like the second option but I do not know how to create the ADO class in the client and exactly how to load the data.

rdvg...@gmail.com

unread,
Jul 7, 2019, 8:33:25 PM7/7/19
to CodenameOne Discussions
Hi,

The data that comes to me from the server can be seen in the attached image. 

dataUser.png




With this in mind create a new class in the "Device" client which implements the PropertyBusinessObject API as shown below:
public class Dispositivo implements PropertyBusinessObject {

    public final LongProperty<Dispositivo> dispositivoId = new LongProperty<>("dispositivoId");
    public final LongProperty<Dispositivo> empresaID = new LongProperty<>("empresaID");
    public final Property<String,Dispositivo> descripcion = new Property<>("descripcion");
    public final Property<String, Dispositivo> numero = new Property<>("numero");

    public final Property<String, Dispositivo> sistema = new Property<>("sistema");
    public final BooleanProperty<Dispositivo> leeHuella = new BooleanProperty<>("leeHuella");
    
//    public final DateProperty<Dispositivo> fechaCambio = new Property>("fechaCambio");
    public final Property<String, Dispositivo> usuarioCambio = new Property<>("usuarioCambio");
    public final Property<String, Dispositivo> estado = new Property<>("estado");  


    private final PropertyIndex idx = new PropertyIndex(this, "Dispositivo", dispositivoId, empresaID, descripcion, numero,
            sistema, leeHuella, usuarioCambio, estado);

    @Override
    public PropertyIndex getPropertyIndex() {
        return idx;
    }

}
In the same way change the entity "User" including the next line.
public final Property<Dispositivo, Usuario> dipositivoId = new Property<>("dispositivoId");

None of these changes worked because to execute the method populateFromMap the data of "Device" is null.

I need some guidance and I appreciate the support.

Shai Almog

unread,
Jul 7, 2019, 10:16:10 PM7/7/19
to CodenameOne Discussions
Hi,
in the server there are several layers. One of them contains the entities (which you've listed) they include the database mapping which includes a lot of internal data such as relations etc.
There's the webservices themselves which include the client side API's. When you invoke the webservice it returns an object, that should be the DAO object. It's an object used to transfer the actual data and should be similar to the entity but not identical. It should include he data as you want the client to see it.

Here it looks like you return the entity or have a DAO that includes a list of entries for dispositivoId instead of a single long value (which might be what you want). You need to decide what you want to see on the client side and create the logic that transfers this. Based on the image you attached you're returning a list, which could also be fine but you need to decide what you want to have on that list and then I can help you with mapping that to a business object on the client side.

rdvg...@gmail.com

unread,
Jul 8, 2019, 4:14:11 AM7/8/19
to CodenameOne Discussions
Hi,

Thanks for support.

From the list that comes from the server, I need all the fields that are part of the "User", plus the following fields that are part of the "Device": dispositivoId (Long), numero (String), descripcion (String) and leeHuella (Boolean).

Shai Almog

unread,
Jul 8, 2019, 11:30:49 PM7/8/19
to CodenameOne Discussions
Hi,
so in the server your webservice or service method needs to convert the entity object (which represents the database schema) into a DAO object which represents the JSON data returned. This DAO object needs to have a structure similar to the one you expect on the client side.

On the server you have a login method. This method should perform that conversion and the DAO should include either the fields or referenced DAO objects (not entity objects!).

rdvg...@gmail.com

unread,
Jul 10, 2019, 2:34:16 AM7/10/19
to CodenameOne Discussions
Hi,

Will you have an example of the conversion to DAO?

Shai Almog

unread,
Jul 10, 2019, 11:37:36 PM7/10/19
to CodenameOne Discussions
Hi,
there are plenty of examples in the book/code. E.g. the login in UserService returns a DAO which the User entity creates.
Reply all
Reply to author
Forward
0 new messages