0
votes

OK, Here is my need. I want to build a web app using Google App Engine Datastore as backend database.

The app allows user to register an account for free. When each registered user can have a saving account, they can deposit or withdraw money in their saving account.

Using the information in this link https://cloud.google.com/appengine/docs/java/datastore/entities

I came up these code

public class RegistrationServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name");
        String email = request.getParameter("email");
        String pass = request.getParameter("pass");

        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();


        Entity user = new Entity("User");
        user.setProperty("name",name);
        user.setProperty("email",email);
        user.setProperty("pass",pass);


        datastore.put(user);
    }

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        DatastoreService ds=DatastoreServiceFactory.getDatastoreService();

        String email = request.getParameter("email");
        String pass = request.getParameter("pass");
        double credit=request.getParameter("credit");
        double debit=request.getParameter("debit");

        int userKeyInt=0;
        Query q=new Query ("User");
        PreparedQuery pq=ds.prepare(q);
        for (Entity u1:pq.asIterable()){
           String emailStr=u1.getProperty("Email").toString();
           String userIDStr=u1.getProperty("UserID").toString();
           String passStr=u1.getProperty("Pass").toString();
           if(emailStr.equals(email) && passStr.equals(pass)) {
                 userKeyInt=Integer.parseInt(userIDStr);
           }
        }
        Key userKey=KeyFactory.createKey("User", userKeyInt);
        try{
           Entity user = ds.get(key);

           Entity savingAccount=new Entity ("SavingAccount");
           savingAccount.setProperty("UserID",  user.getKey());
           savingAccount.setProperty("Debit",debit);
           savingAccount.setProperty("Credit",credit);


         }

         catch (EntityNotFoundException e){
            e.printStackTrace();
         }


    }
}

So the Savingaccount has the field "UserID" that plays a role of foreign key.

Entity user = new Entity("User");
Entity savingAccount=new Entity ("SavingAccount");
savingAccount.setProperty("UserID",  user.getKey());

But I am not sure what I am doing is right because there is no way to check the foreing key constraint, do we need to have Modeling Entity Relationships as stated in this link https://cloud.google.com/appengine/articles/modeling?

If I do need Modeling Entity Relationships, then how to do it?

Note: Each user can have many Saving Accounts.

1
NB1: Do not call toString() when calling getProperty - use cast. Otherwise you will never know if you made a mistake and stored the wrong data type in a property. - Andrei Volgin
NB2: It's very inefficient to loop through all users. Use a query to find one user with the right email. - Andrei Volgin
NB3: Why do you store UserID as a property in User entity? Use IDs auto-generated by the Datastore. Also, IDs are stored as Long values - using integers may lead to problems. - Andrei Volgin
@AndreiVolgin, you said "It's very inefficient to loop through all users. Use a query to find one user with the right email.", so what should I do? Ok, we know that email is unique, then how to get user object when provided email? - Tom
@AndreiVolgin, also, I do not store UserID as a property in User entity, but I do store UserID as a property of SavingAccount entity so that it is similar to Relational Database - Tom

1 Answers

1
votes

You can make SavingAccountEntity a child entity of a UserEntity. It may become useful as you may decide to update your entities in a transaction to preserve data integrity.

With this approach you can retrieve all saving accounts owned by a user with a simple ancestor query on SavingAccountEntity.