Marshalling Undetermined data type - android

With a custom Marshaller I try to map a DynamoDB query to an object
class ownObject {
private int myInteger;
#DynamoDBMarshalling(marshallerClass = MasrshallAsInteger.class)
#DynamoDBAttribute
public int getMyInteger {
return myInteger;
}
public void setMyInteger(int newint) {
myInteger = newint;
}
}
Since the value myInteger in the db has both types String and Number, the SDK throws the Exception: "Expected S in value {N:123,}" if I use the marshaller and "Expected N in value {S:123,}" on an other object if I don't .
Is there any way to force the DynamoDB to use a custom marshaller and parse the value of the Key as String? Or is there any other way to parse a undetermined type of data but using PaginatedQueryList?

I recommend you use the Document SDK to paginate, parse your items into Item objects, paginate, and then convert those Items to your domain.
Table table = new AmazonDynamoDBClient(new DefaultCredentialsProviderChain()).getTable("ownObject");
for (Item item : table.scan()) {
//convert item to your domain object here
}

Related

Firestore update fails with IllegalArgumentException: Invalid data. Unsupported type

When calling
FirebaseFirestore.getInstance().collection("myCollection").document("doc1").update("field1",myObject);
I get the error:
IllegalArgumentException: Invalid data. Unsupported type: com.myProg.objects.MyObject (found in field field1)
Even though I can add myObject to firestore when it is part of myDoc using Set method without a problem.
MyObject class (The simplest example):
public class MyObject{
public int i;
}
Edit:
my DB Structure before attempting:
myCollection ->
doc1:
field0 - "3"
field1 - null
also tried it without field1
So the only way, to update as of now is by using a map. In your case it should look like
Map<String, Object> updateMap = new HashMap();
updateMap.put("field1.i", myObject.i);
FirebaseFirestore.getInstance().collection("myCollection")
.document("doc1").update(updateMap);
I think Firestore should really update the APIs to facilitate updating of nested objects as a whole.
In my case i wanted to update the complex object in the firestore.
public class UserInitialModel {
private List<ServiceItemModel> servicesOffered;
}
public class ServiceItemModel{
private String serviceName;
private String price;
}
it was giving me error when i try to update
java.lang.IllegalArgumentException: Invalid data. Unsupported type:
I Solved it by by using map
List<Map<String,Object>> list=new ArrayList<>();
for (ServiceItemModel model:
mUserInitialPresenter.getUserInitialModel().getServicesOffered()) {
Map<String,Object> servicesOffered=new HashMap<>();
servicesOffered.put("serviceName",model.getServiceName());
servicesOffered.put("price",model.getPrice());
list.add(servicesOffered);
}
dataMap.put("servicesOffered",list);

Firebase data insert issue. Data is not inserted properly

I am trying to insert a POJO to Firebase. However, some of the fields don't seem to be parsed into Firebase, but there is no warning or error.
I have this POJO:
public class Group {
public String name;
public String admin;
public List<String> addedUsers;
public List<String> invitedUsers;
public Group(String name, String admin, ArrayList<String> addedUsers, ArrayList<String> invitedUsers) {
this.name = name;
this.admin = admin;
this.addedUsers = addedUsers;
this.invitedUsers = invitedUsers;
}
public Group() {
// Default constructor required because we have a non-default constructor as well.
}
}
I upload to Firebase by doing so:
DatabaseReference groupRef = ref.child("Groups");
ArrayList<String> addedUsers = new ArrayList<String>();
addedUsers.add("email1#gmail.com");
addedUsers.add("email2#gmail.com");
ArrayList<String> invitedUsers = new ArrayList<String>();
Group newGroup = new Group("GroupName",
"email1#gmail.com", addedUsers, invitedUsers
);
groupRef.push().setValue(newGroup);
I end up with this object in Firebase:
I have a secondary issue now, I manually inserted the data into Firebase, but now I cannot map the Lists onto my Java Object, and are mapped as null, I know I am able to download the data fine;
I'm not sure what you mean that lists are not supported, as it seems that they are supported.
Basic write operations
For basic write operations, you can use setValue() to save data to a
specified reference, replacing any existing data at that path. You can
use this method to:
Pass types that correspond to the available JSON types as follows:
String
Long
Double
Boolean
Map<String, Object>
List<Object>
Pass a custom Java object, if the class that defines it has a default
constructor that takes no arguments and has public getters for the
properties to be assigned.
Firebase supports key value mapping. So lists are not supported. Change it to Map type, keep email addresses as key and assign a boolean value true or false.

Persisting array of strings with greenDao

I'm trying to map an object to database with greenDao. But when it comes to arrays, I don't know how to do it. After receiving JSON from network and deserializing it with GSON, I have objects defined by this class:
public class Car {
Long carId;
String name;
ArrayList<String> listOfLinks;
}
In case of a a different architecture, like this:
public class Car {
Long carId;
String name;
ArrayList<Link> listOfLinks;
}
public class Link {
Long carId;
String link;
}
----
Entity cars = schema.addEntity("Car");
cars.addLongProperty("carId").primaryKey();
cars.addStringProperty("name");
Entity links = schema.addEntity("Link");
links.addStringProperty("name");
links.addIdProperty().primaryKey().notNull().autoincrement();
Property linkProperty = links.addLongProperty("carId").getProperty();
ToMany carToLinks = cars.addToMany(link, linkProperty);
It would is easy. Define some relations, define properties, add foreign key and your done. With arrays I have no clue what to do. Ideas?
That approach is not common when using relational databases.
This is commonly done using to-many relations : instead of using a list of String, you can create a Link entity and then use a list of Link.
Relation toMany is useful when you have a list of your not primitive object, that you can declare like entity that have its own id etc etc etc, and make list of entities (with toMeny). By doing that greenDao makes another table in the base for you new entity with the foreign key of the base entity that contains list. When you have list of primitive type the only way to do is to make converter that converts List into one of the primitive types that greenDao works naturally. You have to do something like this `
import org.greenrobot.greendao.converter.PropertyConverter;
import java.util.Arrays;
import java.util.List;
/**
*DOLE BREEE SQLITE BREEEEEE!!!**
*i choosed to convert List into one string
*that is going to be saved in database, and vice versa
*/
public class GreenConverter implements PropertyConverter, String> {
#Override
public List convertToEntityProperty(String databaseValue) {
if (databaseValue == null) {
return null;
}
else {
List<String> lista = Arrays.asList(databaseValue.split(","));
return lista;
}
}
#Override
public String convertToDatabaseValue(List<String> entityProperty) {
if(entityProperty==null){
return null;
}
else{
StringBuilder sb= new StringBuilder();
for(String link:entityProperty){
sb.append(link);
sb.append(",");
}
return sb.toString();
}
}
}
now above all the properties that are List you have to put
#Convert(converter=yourconverterclass.class, columnType = String.class)
#Entity
public class ShipEntry {
#Id(autoincrement = true)
private long ship_id;
private String name;
private String model;
private String manufacturer;
private String starship_class;
#Convert(converter = GreenConverter.class, columnType = String.class)
private List<String> pilots;
#Convert(converter = GreenConverter.class, columnType = String.class)
private List<String> films ;
}
you can create Converter as a inner class of entitiy, and in that case it has to be declared as staticthat is the only way i have found, but the bad side is that you can not use property that you are converting into query. There might me some typo, but i hope this helps to solve your problem
I also have the same issue, and there no answer (not in official docs, not in google). Please explain how to map List to Entity?
public class Car {
Long carId;
String name;
ArrayList<String> listOfLinks;
}
Can I do something like this?
#Entity(active = true, nameInDb = "CARS")
public class Car {
#Id
private Long id;
#NotNull
#Unique
private String remoteId;
#ToMany(joinProperties = {
#JoinProperty(name = "remoteId", referencedName = "carRemoteId")
})
private List<Links> listOfLinks;
}
#Entity(active = true, nameInDb = "LISTOFLINKS")
public class Links{
#Id
private Long id;
#NotNull
#Unique
private String remoteId;
#SerializedName("listOfLinks")
#Expose
private String listOfLinks;//is it possible?????
private String carRemoteId;
}
Since JPA 2.0, you can use an element collection to persist a Collection of value types. You just need to annotate the attribute with #ElementCollection and the persistence provider will persist the elements of the Collection in an additional database table.
#Entity
public class Author {
#ElementCollection
private List<String> phoneNumbers = new ArrayList<String>();
}
The element collection might seem easier to use than an entity with a one-to-many association. But it has one major drawback: The elements of the collection have no id and Hibernate can’t address them individually.
When you add a new Object to the List or remove an existing one, Hibernate deletes all elements and inserts a new record for each item in the List.
Let’s take a quick look at an example. The following code snippet selects an Author entity and adds a second phoneNumber to the element collection.
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Author a = em.find(Author.class, 1L);
a.getPhoneNumbers().add("42424242");
em.getTransaction().commit();
em.close();
an element collection is an easy but not the most efficient option to store a list of value types in the database. You should, therefore, only use it for very small collections so that Hibernate doesn’t perform too many SQL statements. In all other cases, a one-to-many association is the better approach.

SQLite add a list to a table

I am writing a Xamarin Android application using SQLite and am not sure how to add an object to a table where the object has a list.
Here is my model class:
public class TestObject
{
[PrimaryKey]
public int Id { get; set; }
public string name { get; set; }
public DateTime lastUpdate { get; set; }
public List<TestItem> items { get; set; }
}
Here is my code to add an object to a table:
public void InsertObjectToDatabase<T>(string databasePath, T objType)
{
var db = new SQLiteConnection (databasePath);
db.CreateTable(typeof (T));
db.InsertOrReplace (objType);
}
Here is my code to add a TestObject to a table:
TestObject testObject = new TestObject ();
testObject.Id = 1;
testObject.name = "Test Object 1";
testObject.lastUpdate = DateTime.Now;
sQLiteService.InsertObjectToDatabase<TestObject> (filename, testObject);
This is the error that I am getting:
System.NotSupportedException: Don't know about System.Collections.Generic.List`1[LearningSQLite.TestItem]
Is it possible add a list to a SQLite table?
Thanks in advance
Create another table and refer to the parent table with a foreign key. Once you insert the row in parent, insert all the items from the list in the child. Read more here http://www.sqlite.org/foreignkeys.html
If you are using SQLite.Net-PCL you can use the IBlobSerializer interface to store complex types to a BLOB (byte array). Here is a unit test class that provides more info:
https://github.com/oysteinkrog/SQLite.Net-PCL/blob/master/tests/BlobSerializationTest.cs
For the serializer you can either implement your own or use something like JSON serializers to store the data as JSON.
I am using the BLOB interface to use SQLite as key-value pair caching mechanism:
https://github.com/XForms/Xamarin-Forms-Labs/blob/master/src/Xamarin.Forms.Labs/Plugins/Caching/Xamarin.Forms.Labs.Caching.SQLiteNet/SQLiteSimpleCache.cs

How to parse a JSON response when type is also coming in response

I am getting following json response from a web service call.
as you can see, what type of value we will get in response is also coming in type object.
{"settings":[
{
"name":"name1",
"value":4,
"type":"int"
},
{
"name":"name2",
"value":false,
"type":"boolean"
},
{
"name":"name3",
"type":"array",
"value":[
{
"name":"name3"
}]}]}
how to parse this json?
how to store parsed value in database where i have a table with column names name, value, etc?
Edit:
currently i am converting all values to string because we can't add boolean to database.
private enum Type{
INT("int"), BOOLEAN("boolean"), ARRAY("array"),UNKNOWN_TYPE("");
private String mType;
Type(String type){
mType = type;
}
public static Type toEnum(String type){
for (Type value: Type.values()){
if(value.mType.equals(type)){
return value;
}
}
return UNKNOWN_TYPE;
}
}
String value = null;
switch (Type.toEnum(type)){
case INT:
value = String.valueOf(setting.getInt("value"));
break;
case BOOLEAN:
value = String.valueOf(setting.getBoolean("value"));
break;
case ARRAY:
parseJsonArray();
break;
}
is this the correct approach?
The usual way to deal with data items which could be any of a small known number of types is to use a tagged union. In Java, you'd write one something like this:
// CREATE TABLE dataFromJson (type ENUM('INT', 'BOOLEAN', 'STRING'),
// intval INT, boolval INT, stringval LONGTEXT);
class DataItem {
public enum Type { INT, BOOLEAN, STRING };
public Type m_type;
public int m_int;
public bool m_boolean;
public String m_string;
public PreparedStatement toInsertQuery(Connection conn) {
PreparedStatement ps = conn.prepareStatement("INSERT INTO dataFromJson VALUES (?, ?, ?, ?)");
ps.setString(1, m_type.toString());
if (m_type==INT) ps.setInt(2, m_int); else ps.setObject(2, null);
if (m_type==BOOLEAN) ps.setBoolean(3, m_boolean); else ps.setObject(3, null);
if (m_type==STRING) ps.setString(4, m_string); else ps.setObject(4, null);
return ps;
}
}
Dealing with JSON arrays (and objects) is much trickier; first you'll have to figure out how you want the data to be represented. Do you want the whole array as a string? do you want the first N elements of the array "exploded" into individual columns? do you want to store a single integer array_id, the primary key of a separate and more complicated table ArrayValues? There's all sorts of things you could do here... none of them terribly satisfying on a philosophical level. It depends on what you're going to want to do with the data later.

Categories

Resources