0

I'm trying to get my user from the table : enter image description here

I saved this values via a form (so the cayenne configuration seems to be good).

the UserInfoFactory class is :

public class UserInfoFactory extends _UserInfo implements Serializable {
    private static final long serialVersionUID = 1L;

    public static ObjectContext getContext() {
        @SuppressWarnings("deprecation")
        ServerRuntime runtime = new ServerRuntime("cayenne-myapplication.xml");
        return runtime.newContext();
    }

    @SuppressWarnings("unchecked")
    public static List<UserInfoFactory> getUsersInfo() {

        SQLTemplate select = new SQLTemplate(UserInfoFactory.class,
                "SELECT * FROM mam.userinfo");

        return getContext().performQuery(select);
    }
}

My _UserInfo class is :

package com.example.myapplication.model;

import org.apache.cayenne.CayenneDataObject;

/**
 * Class _UserInfo was generated by Cayenne.
 * It is probably a good idea to avoid changing this class manually,
 * since it may be overwritten next time code is regenerated.
 * If you need to make any customizations, please use subclass.
 */
public abstract class _UserInfo extends CayenneDataObject {

    public static final String ADDRESS_PROPERTY = "address";
    public static final String EMAIL_PROPERTY = "email";
    public static final String FIRSTNAME_PROPERTY = "firstname";
    public static final String LASTNAME_PROPERTY = "lastname";
    public static final String PHONENUMBER_PROPERTY = "phonenumber";
    public static final String USERPASSWORD_PROPERTY = "userpassword";
    public static final String USERPRIVILEGES_PROPERTY = "userprivileges";

    public static final String USERID_PK_COLUMN = "USERID";

    public void setAddress(String address) {
        writeProperty(ADDRESS_PROPERTY, address);
    }
    public String getAddress() {
        return (String)readProperty(ADDRESS_PROPERTY);
    }

    public void setEmail(String email) {
        writeProperty(EMAIL_PROPERTY, email);
    }
    public String getEmail() {
        return (String)readProperty(EMAIL_PROPERTY);
    }

    public void setFirstname(String firstname) {
        writeProperty(FIRSTNAME_PROPERTY, firstname);
    }
    public String getFirstname() {
        return (String)readProperty(FIRSTNAME_PROPERTY);
    }

    public void setLastname(String lastname) {
        writeProperty(LASTNAME_PROPERTY, lastname);
    }
    public String getLastname() {
        return (String)readProperty(LASTNAME_PROPERTY);
    }

    public void setPhonenumber(Integer phonenumber) {
        writeProperty(PHONENUMBER_PROPERTY, phonenumber);
    }
    public Integer getPhonenumber() {
        return (Integer)readProperty(PHONENUMBER_PROPERTY);
    }

    public void setUserpassword(String userpassword) {
        writeProperty(USERPASSWORD_PROPERTY, userpassword);
    }
    public String getUserpassword() {
        return (String)readProperty(USERPASSWORD_PROPERTY);
    }

    public void setUserprivileges(Short userprivileges) {
        writeProperty(USERPRIVILEGES_PROPERTY, userprivileges);
    }
    public Short getUserprivileges() {
        return (Short)readProperty(USERPRIVILEGES_PROPERTY);
    }

}

I'm calling the method like that :

List<UserInfoFactory> users = UserInfoFactory.getUsersInfo();

But the users list return null.

enter image description here That should not be null but one value (test user).

What did I do wrong?

Thanks,

Bob
  • 529
  • 1
  • 7
  • 28

1 Answers1

2

Reason for Cayenne to return null instead of an object is that PK field either not found in the result set or its value is NULL. In your case I think that Cayenne can't find PK in the result as it seems that it's defined as userid id DB and in Cayenne code I see it's USERID.

And please let me give you some general advise about your code. Creating ServerRuntime per request is not really effective solution, you should keep it as application singleton, see this question for details. Moreover ObjectSelect (or SelectQuery if you are using older version of Cayenne) is a better (and really more flexible) way of selecting objects.

You can use it like this:

List<UserInfoFactory> result = ObjectSelect.query(UserInfoFactory.class)
                                     .select(context);
Nikita
  • 266
  • 2
  • 7
  • Perfect ! Thanks a lot for the resolution, I spent too much time on it. I expected an error like 'unreconize USERID' or something like that. Thanks for the improvement. I'll try to do it! – Bob Jun 01 '17 at 19:18
  • 1
    @FannyV you are welcome! As for 'unreconize USERID' this is a problem when using SLQTemplate it's trying to do its best, but silently failing. – Nikita Jun 02 '17 at 08:53
  • Questions about your good advice (thanks for that and sorry I need to improve/learn the 'best pratics') : ObjectSelect or SelectQuery is ok if I want to select for example a count (column name)? I should always select the PK with it, right? In this case, should I use the SQL template? When can I use the SQL Template? – Bob Jun 02 '17 at 20:23
  • 1
    You can select `count(column name)` with latest version of Cayenne (4.0.M5) like this: `ColumnSelect.query(YouClass.class).count(YourClass.COLUMN).selectOne(context);` – Nikita Jun 05 '17 at 12:41
  • 1
    You should use ObjectSelect every time when you want to select your entities, it is designed just for that. Generally you don't need to work with PK directly (select it or update). As for SQLTemplate, you can use it when you need some really custom SQL query, e.g. combining data from different objects, using unions or subqueries. It is essentially just a way to execute any SQL code. – Nikita Jun 05 '17 at 12:56