I get a null object reference error when I try to Query data from my Amazon DynamoDB table like this:
mapper = new DynamoDBMapper(ddbClient);
DataMapperClass dataMapperClass = new DataMapperClass();
dataMapperClass.setHash("theHashValueIset");
String queryString = String.valueOf("theRangeValueIset");
Condition rangeKeyCondition = new Condition()
.withComparisonOperator(ComparisonOperator.BEGINS_WITH.toString())
.withAttributeValueList(new AttributeValue().withS(queryString.toString()));
DynamoDBQueryExpression <DataMapperClass> queryExpression = new DynamoDBQueryExpression<DataMapperClass>()
.withHashKeyValues(dataMapperClass)
.withRangeKeyCondition("rangeAttributeOnTable", rangeKeyCondition)
.withConsistentRead(false);
PaginatedQueryList<DataMapperClass> result = mapper.query(DataMapperClass.class, queryExpression);
My DataMapperClass.class:
#DynamoDBTable(tableName = "myTableName")
public class DataMapperClass {
private String hash;//based on a set of categories I chose
private String objectID; //auto generated
//Hash
#DynamoDBHashKey(attributeName = "hashNameOnMyTable")
public String getHash() { return hash; }
public void setHash(String hash) { this.hash = hash;}
//ObjectID
#DynamoDBRangeKey(attributeName = "rangeAttributeOnTable")
#DynamoDBAutoGeneratedKey
public String getObjectID() {return objectID;}
public void setObjectID(String objectID) { this.objectID = objectID; }
/* other #DynamoDBAttribute*/
}
How can I solve this error I get on the "PaginatedQueryList" code line :
Attempt to invoke interface method 'com.amazonaws.services.dynamodbv2.model.QueryResult com.amazonaws.services.dynamodbv2.AmazonDynamoDB.query(com.amazonaws.services.dynamodbv2.model.QueryRequest)' on a null object reference
Problem solved!
I realised I did not do this in my onCreate():
ddbClient = new AmazonDynamoDBClient(identityManager.getCredentialsProvider());
Related
I want to save and read List<MyObj> to sharedPreferences using Gson.
This is my write method:
private static final String GAS_STATIONS_LIST_KEY = "gasStationsListKey";
#Override
public void save(#NonNull List<MyObj> gasStations) {
saveStr(GAS_STATIONS_LIST_KEY, gson.toJson(gasStations));
}
private void saveStr(#NonNull String key, #Nullable String value) {
sharedPreferences
.edit()
.putString(key, value)
.apply();
}
And this is my read method:
#Override
public List<MyObj> getGasStationList() {
final Type type = new TypeToken<List<MyObj>>() {
}.getClass();
final List<MyObj> gasStations = gson.fromJson(GAS_STATIONS_LIST_KEY, type); // here null
if (gasStations != null && !gasStations.isEmpty()) {
return gasStations;
} else {
return new ArrayList<>();
}
}
But when I try read data I get null (comment in last code part).
How to fix it?
You are not getting the saved json content from shared prefences. You are trying to deserialize the key to a list, not the json content which is saved with that key.
Change this:
final List<MyObj> gasStations = gson.fromJson(GAS_STATIONS_LIST_KEY, type);
To this:
String savedJsonContent = sharedPreferences.getString(GAS_STATIONS_LIST_KEY, null);
final List<MyObj> gasStations = gson.fromJson(savedJsonContent , type);
SharedPreferences only store primitive data Types.
I have a DynamoDB table that has some data. There is a hashkey of "class_id" and a rangekey of "message_timestamp".
In my android code I am attempting to query for messages that are newer than the last message received.
int lastMessageTimestamp = GetNewestTimestamp();
DynamoChatData messagesToFind = new DynamoChatData();
Log.i(TAG,String.valueOf(class_id));
messagesToFind.SetClassId(class_id); // Set to 2 in the debugger at runtime
Condition rangeKeyCondition = new Condition();
rangeKeyCondition.withComparisonOperator(ComparisonOperator.GT.toString());
AttributeValue attributeValue = new AttributeValue();
attributeValue.withN(String.valueOf(lastMessageTimestamp));
rangeKeyCondition.withAttributeValueList(attributeValue);
DynamoDBQueryExpression<DynamoChatData> query = new DynamoDBQueryExpression<>();
query.withHashKeyValues(messagesToFind);
query.withRangeKeyCondition("message_timestamp", rangeKeyCondition);
query.withConsistentRead(false);
PaginatedQueryList result = objectMapper.query(DynamoChatData.class, query);
The DynamoChatData class:
#DynamoDBTable(tableName = "scriyb_chat")
public class DynamoChatData {
private int class_id;
private int message_timestamp;
private String user_name;
private String user_full_name;
private String message_content;
private int message_visible;
private int message_underage;
#DynamoDBRangeKey(attributeName = "message_timestamp")
public int GetMessageTimestamp(){
return message_timestamp;
}
public void SetMessageTimestamp(int _message_timestamp){
message_timestamp = _message_timestamp;
}
#DynamoDBHashKey(attributeName = "class_id")
public int GetClassId(){
return class_id;
}
public void SetClassId(int _class_id){
class_id = _class_id;
}
#DynamoDBAttribute(attributeName = "user_name")
public String GetUsername(){
return user_name;
}
public void SetUsername(String _user_name){
user_name = _user_name;
}
#DynamoDBAttribute(attributeName = "user_full_name")
public String GetUserFullName(){
return user_full_name;
}
public void SetUserFullName(String _user_full_name){
user_full_name = _user_full_name;
}
#DynamoDBAttribute(attributeName = "message_content")
public String GetMessageContent(){
return message_content;
}
public void SetMessageContent(String _message_content){
message_content = _message_content;
}
#DynamoDBAttribute(attributeName = "message_visible")
public int GetMessageVisible(){
return message_visible;
}
public void SetMessageVisible(int _message_visible){
message_visible = _message_visible;
}
#DynamoDBAttribute(attributeName = "message_underage")
public int GetMessageUnderage(){
return message_underage;
}
public void SetMessageUnderage(int _message_underage){
message_underage = _message_underage;
}
}
I followed the basic example outlined here and have read a bunch of posts on this site as well. Not sure why I get the
java.lang.IllegalArgumentException: Illegal query expression: No hash key condition is found in the query
error.
Any insight is appreciated.
Try using refactoring your getter/setter names so that they start with a lowercase letter as is standard Java convention. I believe the mapper looks for getters as methods that start with "get" and I think it's missing yours since they start with a capitol G.
Let me know if this resolves your problem!
Weston
I'm trying to pass an ArrayList of Parcelable objects plus a string value between two activities. This is the code to add the data to the intent and pass it through:
Intent intent = new Intent(this, DisplayLotListActivity.class);
Bundle dataBundle = new Bundle();
dataBundle.putParcelableArrayList(DisplayLotListActivity.EXTRA_LOT_ARRAY, lotList);
dataBundle.putString(EXTRA_LOT_NUMBER, lotNumber);
intent.putExtra(DisplayLotListActivity.EXTRA_DATA, dataBundle);
startActivity(intent);
This is the code that I'm using to get the data out of the intent on the target activity:
Intent intent = getIntent();
Bundle dataBundle = intent.getBundleExtra(EXTRA_DATA);
lotList = dataBundle.getParcelableArrayList(EXTRA_LOT_ARRAY);
lotNumber = dataBundle.getString(LotInquiryActivity.EXTRA_LOT_NUMBER);
When I check the debugger the data structures look correct before the activity is called but when I get into the target activity the data structure has been corrupted. Specifically the ArrayList as 3 elements and it is still 3 elements in size but the second element is null. There is then an additional extra in the bundle which contains the missing element object with a null key. I have images of the debugger before and after but can't put them in the post because of anti-spam rules.
Before: http://i.stack.imgur.com/vDipq.png
After: http://i.stack.imgur.com/JqbF7.png
Is there something I'm missing? This issue occurs whether I use a Bundle or add the ArrayList directly to the intent. This is being run on a Samsung Tab 2 running 4.0.3. This also occurs with a 4.0 emulator.
[Edit]
This is the Parcelable object being used (I've just left the getter and setter methods off the bottom)
public class Lot implements Parcelable{
private String lotn;
private String dsc1;
private String dsc2;
private String litm;
private long itm;
private String locn;
private String mcu;
private String uom1;
private String uom2;
private BigDecimal pqav;
private BigDecimal pqoh;
private BigDecimal sqoh;
private long vend;
private String rlot;
private String ldsc;
private String lots;
private String lot1;
private String lot2;
private String lot3;
private String lotsdsc;
private XMLGregorianCalendar mmej;
private XMLGregorianCalendar ohdj;
public Lot(){
}
public Lot(Parcel source){
lotn = source.readString();
dsc1 = source.readString();
dsc2 = source.readString();
litm = source.readString();
locn = source.readString();
mcu = source.readString();
uom1 = source.readString();
uom2 = source.readString();
itm = source.readLong();
pqav = new BigDecimal(source.readString());
pqoh = new BigDecimal(source.readString());
sqoh = new BigDecimal(source.readString());
vend = source.readLong();
rlot = source.readString();
ldsc = source.readString();
lots = source.readString();
lot1 = source.readString();
lot2 = source.readString();
lot3 = source.readString();
lotsdsc = source.readString();
try{
mmej = DatatypeFactory.newInstance().newXMLGregorianCalendar(source.readString());
}catch (Exception exc){
mmej = null;
}
try{
ohdj = DatatypeFactory.newInstance().newXMLGregorianCalendar(source.readString());
}catch (Exception exc){
ohdj = null;
}
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(lotn);
dest.writeString(dsc1);
dest.writeString(dsc2);
dest.writeString(litm);
dest.writeString(locn);
dest.writeString(mcu);
dest.writeString(uom1);
dest.writeString(uom2);
dest.writeLong(itm);
if(pqav != null){
dest.writeString(pqav.toPlainString());
} else {
dest.writeString("0");
}
if(pqoh != null){
dest.writeString(pqoh.toPlainString());
} else {
dest.writeString("0");
}
if(sqoh != null){
dest.writeString(sqoh.toPlainString());
} else {
dest.writeString("0");
}
dest.writeLong(vend);
dest.writeString(rlot);
dest.writeString(ldsc);
dest.writeString(lots);
dest.writeString(lot1);
dest.writeString(lot2);
dest.writeString(lot3);
dest.writeString(lotsdsc);
if(mmej != null){
dest.writeString(mmej.toXMLFormat());
} else {
dest.writeString("");
}
if(ohdj != null){
dest.writeString(ohdj.toXMLFormat());
} else {
dest.writeString("");
}
}
/**
*
*/
public static final Parcelable.Creator<Lot> CREATOR
= new Parcelable.Creator<Lot>() {
public Lot createFromParcel(Parcel in) {
return new Lot(in);
}
public Lot[] newArray(int size) {
return new Lot[size];
}
};
OK, for anyone that comes back to this question there's two problems that I found which I assume combined to cause this behavior. The issues all related to the Parcelable object I was using so thanks to Todd for at least pointing me in this direction.
Firstly, I had a simple error where I had missed a readString() in my constructor of the Parcelable object. So basically I was writing out n elements and reading in n - 1 elements. The second issue is that Android does not implement the javax.xml.datatype library which means that XMLGregorianCalendar is not available. As I didn't need the features of this class on the client side (there's a Java Web Application that it talks to which does use it) I just converted over to a simple java.util.Date object instead.
My question is about an error occurred when I use my followed class:
public class ClassePai {
private int ID;
private String Nome;
private ArrayList<ClasseFilho> listaParentes;
public ClassePai( int id, String nome){
this.ID = id;
this.Nome = nome;
listaParentes = new ArrayList<ClasseFilho>();
}
public void addParente(ClasseFilho classeFilho) {
listaParentes.add(classeFilho);
}
public ClasseFilho getParente( int index ){
return listaParentes.get(index);
}
public int length(){
return listaParentes.size();
}
public String Nome(){
return this.Nome;
}
public int ID(){
return this.ID;
}
}
and this "son" class:
public class ClasseFilho {
private String Nome;
private String Grau;
public ClasseFilho( String nome, String grau ){
this.Nome = nome;
this.Grau = grau;
}
public String Nome(){
return this.Nome;
}
public String Grau(){
return this.Grau;
}
}
This is my Activity:
public class TesteClasseActivity extends Activity {
private ClassePai cp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
cp = new ClassePai( 1, "Junior" );
cp.addParente( new ClasseFilho( "Vinicius", "filho" ) );
cp.addParente( new ClasseFilho( "Luciene", "namorada" ) );
//old call returning error
//Toast.makeText(getApplicationContext(), cp.length(), Toast.LENGTH_SHORT).show();
Toast.makeText(getApplicationContext(), String.valueOf( cp.length() ), Toast.LENGTH_SHORT).show();
cp.addParente( new ClasseFilho( "Veraldo", "pai" ) );
cp.addParente( new ClasseFilho( "Sônia", "mãe" ) );
Toast.makeText(getApplicationContext(), String.valueOf( cp.length() ), Toast.LENGTH_SHORT).show();
( (TextView) findViewById(R.id.edit) ).setText( cp.Nome() );
Button bt = (Button) findViewById(R.id.button);
bt.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), cp.getParente(1).Nome(), Toast.LENGTH_SHORT).show();
}
});
//my try of doing this, but don't work
JSONObject obj = new JSONObject();
obj.put("teste", cp);
// BUT unfortunatelly
//
// obj.toString() returns this:
//
// {"teste":"my.package.name.ClassePai#40516650"}
//
// BUT...
//wondering on net, I've deceided to try Gson:
//first part: object to string
Gson obj = new Gson();
obj.toJson(cp);
String obj_in_xml = obj.toString();
Toast.makeText( getApplicationContext() , obj_in_xml, Toast.LENGTH_SHORT).show();
//no error, appear works fine, but...
//second part: string to object
Gson obj2 = new Gson();
ClassePai new_cp = obj2.fromJson( obj_in_xml, ClassePai.class);
Toast.makeText( getApplicationContext() , new_cp.Nome(), Toast.LENGTH_SHORT).show();
//give me an error com.google.gson.stream.MalformedJsonException
//and I could't find my properties in obj.toString(), but only codes like:
//
//adapter=com.google.gson.internal.bind.TypeAdapters$7#40529278]
//
// and don't find any of the object's string properties in the obj.toString() string
//
// what I'm doing wrong????
}
}
How can I do to save this object with children in a text format, and after load from String to the objects again?
Please help me!!!
May be the problem is here:
Toast.makeText(getApplicationContext(), cp.length(), Toast.LENGTH_SHORT).show();
Here the second parametr must be an integer reference to a string resource or string value. If you want to show the size as a toast message use this variant:
Toast.makeText(getApplicationContext(), String.valueOf(cp.length()), Toast.LENGTH_SHORT).show();
Update
To convert JSON Object to String use:
String myString = myJSONObject.toString();
String to JSONObject:
JSONObject myJSONObject = getJSONObject(myString);
The first problem is that, you can't pass a int type to the method "Toast.makeText". You can convert the int to the String and show it. By String lengthString = String.valueOf(cp.length()).
The second problem you can use the xml to save and read string.
JSONObject person = new JSONObject();
String spmnoName = "spmno";
try{
person.put("name", spmnoName);
String getString = person.getString("name");
}catch(JSONException ex){
throw new RuntimeException(ex);
}
I have defined a class that contains properties of a specific answer object
The class look like this and is defined inside the class that is trying to use it
protected class Answer {
String QuestionId = "";
String AnswerValue = "";
String Correct = "";
public String getQuestionId() {
return QuestionId;
}
public void setQuestionId(String arg) {
QuestionId = arg;
}
public String getAnswerValue() {
return AnswerValue;
}
public void setAnswerValue(String arg) {
AnswerValue = arg;
}
public String getCorrect() {
return Correct;
}
public void setCorrect(String arg) {
Correct = arg;
}
}
Not sure if the above is OK
When I try to use the class I get null pointer errors
I'm using it like this
ArrayList<Answer> answerList = new ArrayList<Answer>();
for(int a=0;a<answers.getLength(); a++){
Element eAnswer = (Element) answers.item(a);
Answer anAnswer = new Answer;
NodeList answer_nodes = eAnswer.getChildNodes();
for (int ian=0; ian<answer_nodes.getLength(); ian++){
Node ans_attr = answer_nodes.item(ian);
String tag_name = ans_attr.getNodeName();
if(tag_name.equalsIgnoreCase("answer")){
anAnswer.setAnswerValue(ans_attr.getTextContent());
}
}
answerList.add(anAnswer);
}
Answer anAnswer = new Answer; gives a compilation error
All I'm trying to do is to create a list of answers which have a name value pair for a number of properties
Any guidance on this greatly appreciated - Especially if there is a better way
Answer anAnswer = new Answer();