updating certain fields to prevent overwriting - java

I'm developing a Android-application using StackMob. Now I'm at the point that I want to save an object but not all his properties let's take this example.
class A extends StackMobModel
{
String UserOneInput;
String UserTwoInput;
}
Now I have two people using one instance of class A at the same time. User one puts his information in UserOneInput and user two in UserTwoInput. Now if user one saves hits information while user two already has fetched this object the situation would be
class A extends StackMobModel
{
String UserOneInput = "User one his input";
String UserTwoInput = null;
}
For user one while user two has
class A extends StackMobModel
{
String UserOneInput = null;
String UserTwoInput = null;
}
Now if player two saves his data it's saved as it is in his situation so we get
class A extends StackMobModel
{
String UserOneInput = null;
String UserTwoInput = "User two input";
}
User one his input is overwritten. I can fetch the object again before saving but if you use it on mobile networks the latency can still cause the same problem. (User two saves his information between the time that use one does a fetch and save)
I looked into the javadoc and only found a function that you can use to select certain fields but it says that won't work for saving.
Is there such an method for saving only certain fields of a class? Or is there some different model I should use to prevent overwriting?

The class does not know who is the owner, in order to know which one String to save.
This class must be decomposed to
class Answer {
String answer;
....
}
and
class Question {
Answer userOne;
Answer userTwo;
....
}
Each user has access to and saves his own Answer and the Question knows the Answers of the users.

Related

Grails Domain Class String List Not Persisting

This is in grails 2.5.6 code. I have a domain class that uses inheritance. One of the subclasses contains a list of strings stored in the variable values. When calling .save(), the domain class itself saves correctly with the right inheritance behavior, but the values do not get saved. Here is my domain classes:
abstract class Condition implements ICondition, IMarshaler {
String field;
static mapping = {
tablePerHierarchy false;
}
...
}
class ListCondition extends Condition {
static hasMany = [values: String];
List<String> values;
...
}
Attempting to save a new list condition and the getting it again from the database shows that there is no values.
ListCondition condition = new ListCondition(field: 'someField', values: ['test', 'otherTest'])
condition.save()
println ListCondition.getAll()[0].values.size() // Prints 0
Stumbled upon a similar issue. Try condition.save(flush: true) or even better try running your persistence-logic inside a transaction. This seems to make the difference and is considered best-practice anyways.

How to tell that a field is not going to be saved

I have a class which is used to get transfer data from the one application to another and then also to update if changes were made.
public class Data {
private String name;
private String number;
private String info;
... getters/setters...
}
Let's say name and number will be updated if you change them but e.g. info is not. What's the best way to tell programmers in the future that this is intended so they can recognize it immediately?
Update:
It's encoded as a JSON file and when I get it back I don't care about the info field anymore. It could be empty
You can create your custom annotation, specific to your application. If you are using any framework like Hibernate you can use #transient.
Probably not the correct way, but if you are just talking about "informing" other programmers, you could simply put the transient keyword on your info field.
But of course, that would be really "informal"; as it would probably not at all affect how your framework is dealing with your fields.
I would use serialisation combined with the transient keyword
What is object serialization?
import java.io.*;
import java.util.*;
// This class implements "Serializable" to let the system know
// it's ok to do it. You as programmer are aware of that.
public class SerializationSample implements Serializable {
// These attributes conform the "value" of the object.
// These two will be serialized;
private String aString = "The value of that string";
private int someInteger = 0;
// But this won't since it is marked as transient.
private transient List<File> unInterestingLongLongList;
There's no indication in your file that name or number are being persisted.
If you are going to put behavior into the file in some durable way, this isn't just a file, it's a representation of an object, where data and the related behavior live as one. Write a method clarifying the intent.
public boolean isStorable() {
boolean isOk = true;
isOk &= (name != null && name.length() > 0);
isOk &= (number > 0);
return isOk;
}
Makes it clear that not every one of these items contribute to being able to store the object, and that not every value within these items contribute to a valid storage state.
It also makes it clear that this object permits invalid states within its private data. That's a code smell that could indicate a design flaw. Perhaps you should look into whether that is a design flaw, and if it is, then fix it.
Start here https://docs.oracle.com/javaee/6/tutorial/doc/bnbpz.html
Almost any programmer seing a POJO like this will know that behaviour is what you explained....
#Table(name = "data")
public class Data {
#Id
#Column(name = "name")
private String name;
#Column(name = "number")
private String number;
private String info;
... getters/setters...
}
UPDATE: It's encoded as a JSON file and when I get it back I don't care about the info field anymore. It could be empty

Play framework merge POST with model

I am trying to learn the Play framework however i hit a roadblock and the documentation did not cover my issue (google resulted in nothing). What i am trying to do is making a multi page form that updates every time to the database.
Lets say the form is made in 5 steps and they cant be on the same page. What i've got working is that the first page works like intended (this also has the required data, the rest is optional)
ERROR executing DML bindLog[] error[Invalid value "null" for parameter "SQL"
After some searching i found that this had to do with the fact that the second page does not have the required data and thus sets those values to null. Meaning when i want to save the object it cant because all the other values are null.
Now my current saving code is pretty straightforward:
User userUpdate = Form.form(User.class).bindFromRequest().get();
userUpdate.update(id);
(the id value is from the action)
i've also tried the following:
User userUpdate = Form.form(User.class).fill(User.find.byId(id)).bindFromRequest().get();
userUpdate.update(id);
And in both cases my program crashes because of the null values.
So what i need is a push in the right direction to merge the current model with the form data so that i can save it. If someone has an good example on how to do it that would be really helpful!
P.s. this is my current model:
#Entity
public class User extends Model{
#Id
public Long id;
public String username;
public String firstname;
public String lastname;
public static Finder<Long,User> find = new Finder<Long,User>(Long.class, User.class);
public Form getUserFormByID(Long id){
Form<User> userForm = Form.form(User.class);
if(id > 0){
userForm = userForm.fill(
this.find.byId(id)
);
}
return userForm;
}
}

how to use same string in two java files

Sorry for my bad English and for maybe stupid question but I'm new in Java.
I need use same string in 2 java files for example:
In first java file I've got code for sending emails, I've got string set to default email:
public String mail = new String ("lala#gmail.com");
and I use this string in code for send email:
email.addTo(mail);
In second java file something like set up where can user set new email address I want to have same string, connected with string in first java file. When user put new email String mail will be change to new email address and in email.addTo(mail); will be use this new address
How can I do this?
use Shared Preferences, you can store it as key-value Pair. value being your email and key can be any unique string which you want to identify it with.
I'm a bit confused with the question, but I'll take a stab at it. Basically, you would like to have one String in a given file be used in multiple locations. This is easily done using class-level variables and making them publicly accessible.
For example, in the file:
EmailObject.java
public class EmailObject {
public static final String mail = "lala#gmail.com";
// The rest of your code
}
Another file can access this like so:
OtherObject.java
public void sendEmail() {
EmailMessage email = new EmailMessage();
email.addTo(EmailObject.mail);
}
Note the static and final modifiers on the original. This ensures that you do not need an actual instance of EmailObject to access the string and it also ensures that the string is never modified accidentally by some other object.
There are, of course, other ways to do this, but this one matches your code the most. This is also a very "Java" solution. Android has other ways to share data (as indicated by the other answer).
The simplest way that I would not recommend is to have a public static field:
class A {
public static String commonString;
}
class B {
public void methodThatUsesString () {
// Do stuff with the string
Log.d("I have the string", A.commonString);
}
}
If you have two Activities, and one starts another, you can send data through Intents.
The forementioned SharedPreferences way is a good solution too, if the email address is a persistent thing, a preference if you will, and not just data reqired for an operation.
You can keep a reference of one instance of a class in the otherone, and access it's fields through it:
class A {
public String commonString;
}
class B {
private final A instaceOfA;
public B (A instanceOfA) {
this.instanceOfA = instanceOfA;
}
public void methodThatUsesString () {
// Do stuff with the string
Log.d("I have the string", instanceOfA.commonString);
}
}
Or even use a getter or setter if performance is not an issue.
Many answers depending on how the string will be used.
If it's a constant string, one that will never change, never use final static String
public final static String AUTHOR_MAIL = "lala#gmail.com";
Then you can use it in a static way wherever you want.
email.addTo(MyClass.AUTHOR_MAIL);
If this String will be used in different Activities you can not access it directly (you can not tell if the other Activity is still alive). You have to use Persistence Mechanisms such as SharedPreferences or directly send needed data in your Intent.
If it's in a helper class inside your Activity, you can just use mObject.mail to get it.

how do I pass information from one class to another

I am creating a program which allows the user to input details of customers. When they have saved each customers record there is the choice to add additional information. I am having trouble getting the the name of the saved file in my append class. I need the filename so I can then save the additional information to the same file already created for the customer. How do I pass the file name from one file to another.
File FName = fileChooser.getSelectedFile();
String name = FName.getName();
public String getname() { return name; }
This code is in my customer class how do I get this information in my append class??
Possibly something like this:
Customer customer = new Customer();
// do some stuff with your customer object, including initiating the File and saving its name to a String field called name
Append append = new Append();
append.foo(customer.getName()); // passes the name of the file to the foo method of class Append
This assumes that you'll only want the name of the file in that one method (though you could save it to a field as part of method foo()). You'd need to implement a method foo(String name) in class Append.
Another option would be to pass it as a constructor of Append:
Append append = new Append(customer.getName());
append.foo();
For this, you'd need to implement a constructor Append(String name) in class Append.
There are a couple of ways to do this depending on what exactly it is you are trying to do.
Give the Append class a member variable of the Customer class
Have the Append class constructor take a parameter that would refer to a Customer, such as a String of name or a Customer object as this is Java
Your question is not entirely clear to me, but here's a problems you might run into based on your description:
What is getName() supposed to return, the name of the file, or the name of the person? If it's supposed to return the file name, then use getFileName() instead - it's clearer!
I don't really understand why you'd need an Append class. Personally, I'd handle appending additional info inside the Customer class. I'd do it so that every time a value is added or changed, the info is saved back into the file like:
class Customer {
public void setForename(String forename) {
this.forename = forename;
save();
}
public void setSurname(String surname) {
this.surname = surname;
save();
}
public void save() {
// clear file
// add new content
String fileContents = "forename="+forname+"&surname="+surname;
// save to file
}
Maybe I'm not understanding your needs correctly though...
In addition to DeadPassive's answer of associating the additional information with the Customer object:
The saving of the Customer data does not belong in the Customer Class. The logic of persisting the data belongs in a seperate layer than the code that deals with manipulating the problem domain. A controller or service class seems like a more appropriate place to put the persistance logic.

Categories

Resources