(SAVING DATA WITH RELATION USING BACKENDLESS 4.0)
I would like to save data with one to one relation.
example: -person_table have a relation with adress_table
the data is save in person_table and address_table without relation. how can make this? #backendless4.0
Adress newAdress= new Adress();
newAdress.setAdress("43 Street");
newAdress.setPersonId(Person);
Backendless.Persistence.save(newAdress, new AsyncCallback< Adress >() {
#Override
public void handleResponse(Adress response) {
}
#Override
public void handleFault(BackendlessFault fault) {
fault.getMessage();
}
});
I find the result:
for save with relation in backendless 4.0 you need to save the object first and save the relation after.
ref link 1 : ADD RELATION WITH OBJECTS
ref link 2 : save object with relation using REST API
Person personObject = // personObject retrieval is out of scope in this example
Adress objectAdress = // addressObject retrieval is out of scope in this example
ArrayList< Person > personCollection = new ArrayList< Person >();
personCollection.add( personObject );
Backendless.Data.of( Adress.class ).addRelation( objectAdress, "personId:Adress:n", personCollection,
new AsyncCallback<Integer>()
{
#Override
public void handleResponse( Integer response )
{
progressDialog.dismiss();
Log.i( "MYAPP", "related objects have been added");
}
#Override
public void handleFault( BackendlessFault fault )
{
}
} );
Related
I need to show a unit of measure from the product user selection and that when selecting it shows its price at the same time
Alert Dialog with data using floating btn
I don't know if it should be with the ViewModel or the repository in the second, because it must vary from the input of the first
I use the generic MVVM model pattern where I have my dao, entity (POJO) and ViewModel with Repo.
The other problem it's how show with Repository specific columns
I want to use specifics columns from my POJOS using method to string I created, not the toString override.
When this is ready I need this data inside the ActivityHost to check if is empty, don't send the data to the other fragments and the server.
In summary this is all the things:
the final display that I need
Please let me know if there is more data that I could provide.Thanks (I can't use Kotlin btw)
The result I want it's use the data to pass it to a RecycleView and then will go to my ActivityHost of fragmentProduct
This is part of the class:
Fragment Product
//initilization of variables,viewModels and Repos:
...
other functions
...
private void alertAddProducto() {
// build of the MaterialAlertDialog customView
final ArrayAdapter<Productos> dataAdapter = new ArrayAdapter<>(getActivity(),
R.layout.item_listado_layout, new ArrayList<>(0));
tiProducto.setAdapter(dataAdapter);
mProductosRepository.getAllProductosLiveData().observe(requireActivity(), items -> {
assert items != null;
Collections.sort(items, (obj1, obj2) -> obj1.getPRODUCTO_DESCRIPCION().compareToIgnoreCase(obj2.getPRODUCTO_DESCRIPCION()));
dataAdapter.addAll(items);
dataAdapter.notifyDataSetChanged();
});
//the other mRepo that I don't know if is necessary, (should be ViewModel)?
the second AutocompleteView needs the user input and then it should show other fields in my alert
like price ,quantity and subtotal (disabled)
}
ilustrative pictures
DAO
#Dao
public interface ProductosDao {
#Insert
void insert(Productos producto);
#Update
void update(Productos producto);
#Delete
void delete(Productos producto);
#Query("DELETE FROM productos_table")
void deleteAll();
#Query("SELECT * FROM productos_table ORDER BY PRODUCTO_ID DESC")
LiveData<List<Productos>> getAllProductosLiveData();
#Query("SELECT * FROM productos_table ")
LiveData<List<Productos>> getAllUnidadesMedida();
}
TABLE
#Entity(tableName = "productos_table")
public class Productos {
#PrimaryKey(autoGenerate = true)
private int AUTOGENERADO_ID;
private String PRODUCTO_DESCRIPCION;
...
public Productos(int AUTOGENERADO_ID,
...) {
this.AUTOGENERADO_ID = AUTOGENERADO_ID;
this.PRODUCTO_DESCRIPCION = PRODUCTO_DESCRIPCION;
}
...
#Override
public String toString() {
return PRODUCTO_ID + " " + PRODUCTO_DESCRIPCION;
}
public String getStringPRODUCTO_DESCRIPCION() {
return PRODUCTO_DESCRIPCION;
}
}
I want to use this methods not toString in AutocompleteView
ActivityHost
public class ActaHost extends DrawerBaseActivity{
//init variables
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityPacHostBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
FragmentManager fm = getSupportFragmentManager();
adapter = new ActaAdapter(fm, getLifecycle());
...
initViewPager2();
mSharedViewModel = new ViewModelProvider(this).get(ActaSharedViewModel.class);
observable(mSharedViewModel);
}
observable(SharedViewModel mSharedViewModel){
mProductoViewModel.getAllProductos().observe(this, Productos-> {
assert Productos!= null;
Collections.sort(Productos, (obj1, obj2) -> obj1.getProducto().compareToIgnoreCase(obj2.getProducto()));
for (int i = 0; i < Productos.size(); i++) {
ProductosList.add(Productos.get(i));
Log.i("ProductosList", Productos.get(i) + String.valueOf(ProductosList.get(i).getProducto()));
}
Log.i("ProductosList", ProductosList.toString());
});
}
}
Here's my code to delete all entities for a given type:
#Override
public boolean deleteEntities(String instance, final String storeName) {
final boolean[] success = {false};
final PersistentEntityStore entityStore = manager.getPersistentEntityStore(xodusRoot, instance);
try {
entityStore.executeInTransaction(new StoreTransactionalExecutable() {
#Override
public void execute(#NotNull final StoreTransaction txn) {
EntityIterable result = txn.getAll(storeName);
final boolean[] hasError = {false};
for(Entity entity : result) {
if(!entity.delete()) {
hasError[0] = true;
}
}
success[0] = !hasError[0];
}
});
} finally {
////entityStore.close();
}
return success[0];
}
Question:
Is this the right approach to delete all existing entities for a given entity type?
When this method is executed, all entities are indeed removed but the Enity type is sitll there, how to properly delete a enity type?
There is PersistentEntityStore#renameEntityType to rename entity type as part of a public api. To delete entity type at all you can use PersistentEntityStoreImpl#deleteEntityType. It's not a part of PersistentEntityStore api but method is public and you can use it.
Also when you deleting entity type do not forget that you also need to clear all links points to entities of this type.
I am fetching data from json api I have set PrimaryKey as state. This is the Json data I am fetching:
records[
{
"id":"192693681",
"timestamp":"1500204608",
"state":"Rajasthan",
"district":"Rajasamand",
"market":"Rajasamand",
"commodity":"Sugar",
"variety":"Shakkar",
"arrival_date":"16/07/2017",
"min_price":"4000",
"max_price":"4100",
"modal_price":"4050"
},
{
"id":"192693701",
"timestamp":"1500204608",
"state":"Rajasthan",
"district":"Rajasamand",
"market":"Rajasamand",
"commodity":"Wheat",
"variety":"Farmi",
"arrival_date":"16/07/2017",
"min_price":"1600",
"max_price":"1650",
"modal_price":"1625"
},
{
"id":"192693721",
"timestamp":"1500204608",
"state":"Rajasthan",
"district":"Rajasamand",
"market":"Rajasamand",
"commodity":"Wheat",
"variety":"Lokwan",
"arrival_date":"16/07/2017",
"min_price":"1550",
"max_price":"1600",
"modal_price":"1575"
}
]
This is my query to return the market data for every state:
private void populateMarketData(String state){
cityAdapter = new CityAdapter(mRealm.where(Records.class).equalTo(Constants.STATE, state).findAll(), this);
cityRecyclerView.setAdapter(cityAdapter);
Log.d(TAG, "Total Cities" + String.valueOf(cityAdapter.getData().size()));
cityAdapter.notifyDataSetChanged();
}
This is my query to return all commodities for the market with the states:
#Override
public void onMarketClicked(String cityName) {
tradeAdapter = new TradeAdapter(mRealm.where(Records.class)
.equalTo(Constants.MARKET, cityName).findAll(), this);
tradeRecyclerView.setAdapter(tradeAdapter);
}
This is GcmTaskService to update data in background service:
Realm.init(mContext);
List<Records> records = new MandiDataHandler().getMandiQuotes(url);
SaveMandi saveMandi = new SaveMandi(state, records);
Realm realm = new RealmController(getApplication()).getRealm();
realm.beginTransaction();
realm.copyToRealmOrUpdate(saveMandi);
realm.commitTransaction();
realm.close();
This is DataHelper to save the data from Json API
#PrimaryKey
private String state;
private RealmList<Records> recordsRealmList = new RealmList<>();
public SaveMandi(){}
public SaveMandi(String state, List<Records> recordsList) {
try {
this.state = state;
for (Records records: recordsList ) {
records = new Records(records.getId(), DateUtils.getRelativeTimeSpanString(
Long.parseLong(records.getTimestamp())).toString(), records.getState(), records.getMarket(),
records.getCommodity(), records.getVariety(), records.getMin_price(), records.getMax_price());
this.recordsRealmList.add(records);
}
}catch (Exception e){
e.printStackTrace();
}
}
The problem in my RealmRecyclerView it either returns single item when I set the PrimaryKey to state, else when I set the PrimaryKey to id it returns multiple duplicate data. I am not sure about where I might be wrong.
You want to choose your PrimaryKey to be something that will only match when they are (what you deem as) "equal", much like an equals() method. If you put two RealmObjects with the same PrimaryKey into Realm only one of them will show up in Realm since there can only be one object for each distinct PrimaryKey.
For example if I have a RealmObject a with a PrimaryKey of 1 in realm and I put another RealmObject b with a PrimaryKey of 1 into Realm, a will be deleted with b since there can only be one object for every PrimaryKey.
A good tool to look through your Realm databases is Stetho, I highly recommend it for debugging applications using Realm.
I have a problem trying to sort specific columns from a cell table, whcih is populated from the DB, using RPC. Basically I'm trying to sort the family name column alphabetically, and it's just not working. Table gets fully populated, but sorting does not work.
Any ideas why ?
Thanks in advance
// Create the family name column.
final TextColumn<ContactInfo> familyNameColumn = new TextColumn<ContactInfo>() {
#Override
public String getValue(ContactInfo object) {
return object.getFamilyName();
}
};
table.setColumnWidth(familyNameColumn, 20, Unit.PCT);
// Make the family name sortable
familyNameColumn.setSortable(true);
// Add the columns
table.addColumn(familyNameColumn, UserMenuConstants.FAMILY_NAME_COLUMN);
table.addColumn(familyAdministratorColumn, UserMenuConstants.FAMILY_ADMINISTRATOR_COLUMN);
table.addColumn(apartmentNuberColumn, UserMenuConstants.FAMILY_APARTMENT_NUMBER_COLUMN);
table.addColumn(emailColumn, UserMenuConstants.EMAIL_ADDRESS_COLUMN);
table.addColumn(phoneNumberColumn, UserMenuConstants.PHONE_NUMBER_COLUMN);
DBGetContactInfoAsync rpcService = (DBGetContactInfoAsync) GWT.create(DBGetContactInfo.class);
ServiceDefTarget target = (ServiceDefTarget) rpcService;
String moduleRelativeURL = GWT.getModuleBaseURL() + "DBGetContactInfoImpl";
target.setServiceEntryPoint(moduleRelativeURL);
rpcService.getContacts(new AsyncCallback<List<ContactInfo>>() {
#Override
public void onSuccess(List<ContactInfo> result) {
table.setRowCount(result.size());
ListDataProvider<ContactInfo> dataProvider = new ListDataProvider<ContactInfo>();
dataProvider.addDataDisplay(table);
List<ContactInfo> list = dataProvider.getList();
for (ContactInfo contactInfo : result) {
list.add(contactInfo);
}
ListHandler<ContactInfo> listHandler = new ListHandler<ContactInfo>(result);
listHandler.setComparator(familyNameColumn, new Comparator<ContactInfo>() {
#Override
public int compare(ContactInfo o1, ContactInfo o2) {
return o1.getFamilyName().compareTo(o2.getFamilyName());
}
});
table.addColumnSortHandler(listHandler);
}
#Override
public void onFailure(Throwable caught) {
...
}
});
You are making two copies of your data: result and list. The list is connected with dataProvider:
List<ContactInfo> list = dataProvider.getList();
and the listListener is connected with result:
ListHandler<ContactInfo> listHandler = new ListHandler<ContactInfo>(result);
so you are displaying list but sorting the result.
Just replace
new ListHandler<ContactInfo>(result);
with
new ListHandler<ContactInfo>(list);
and it works.
EDIT:
You can make it even easier and pass the result to the ListDataProvider constructor:
new ListDataProvider<ContactInfo>(result);
Then, you don't need to copy values to the list and just do
new ListHandler<ContactInfo>(dataProvider.getList());
Move most of the code in your onSuccess method out of there - there is no reason to call it each time a data is loaded. For example, you can/should set a Comparator only once, etc.
Tell your table which column to use for sorting:
table.getColumnSortList().push(familyNameColumn);
When you finish loading new data, tell your table to sort it:
ColumnSortEvent.fire(table, table.getColumnSortList());
I am using a simply city SuggestBox where I am getting list of cities from the database and putting them in GWT suggestBox oracle.
After that user can select his city from the suggestBox suggestions and user saves his record. For example, he will select "London" from the suggestbox list.
Now when user saves his record, I will not save "London" in the database for that user, instead I want to save "3" (london ID) in database.
For this what I am doing is like this:
public MultiWordSuggestOracle createCitiesOracle(ArrayList<City> cities){
for(int i=0; i<cities.size(); i++){
oracle.add(cities.get(i).getCity()+","+cities.get(i).getCityId());
}
return oracle;
}
Now, I have the city and cityID both displaying in suggestBox and then can save from there 'city' and 'cityId'.
Everything works fine, but it doesn't looks good:
like it dispays as "London,3" and so on in the suggestBox suggestions..
I don't want to show this 3, how and where can I save this Id(3) for future use?
You can also create your own typed Suggestion-Box. You need to implement "Suggestion" and extend "SuggestOracle".
Super simple version may look:
// CityOracle
public class CityOracle extends SuggestOracle {
Collection<CitySuggestion> collection;
public CityOracle(Collection<CitySuggestion> collection) {
this.collection = collection;
}
#Override
public void requestSuggestions(Request request, Callback callback) {
final Response response = new Response();
response.setSuggestions(collection);
callback.onSuggestionsReady(request, response);
}
}
//CitySuggestion
public class CitySuggestion implements Suggestion, Serializable, IsSerializable {
City value;
public CitySuggestion(City value) {
this.value = value;
}
#Override
public String getDisplayString() {
return value.getName();
}
#Override
public String getReplacementString() {
return value.getName();
}
public City getCity() {
return value;
}
}
// Usage in your code:
// list of cities - you may take it from the server
List<City> cities = new ArrayList<City>();
cities.add(new City(1l, "London"));
cities.add(new City(2l, "Berlin"));
cities.add(new City(3l, "Cracow"));
// revert cities into city-suggestions
Collection<CitySuggestion> citySuggestions = new ArrayList<CitySuggestion>();
for (City city : cities) {
citySuggestions.add(new CitySuggestion(city));
}
//initialize city-oracle
CityOracle oracle = new CityOracle(citySuggestions);
// create suggestbox providing city-oracle
SuggestBox citySuggest = new SuggestBox(oracle);
// now when selecting an element from the list, the CitySuggest object will be returned. This object contains not only a string value but also represents selected city
citySuggest.addSelectionHandler(new SelectionHandler<SuggestOracle.Suggestion>() {
#Override
public void onSelection(SelectionEvent<Suggestion> event) {
Suggestion selectedItem = event.getSelectedItem();
//cast returned suggestion
CitySuggestion selectedCitySuggestion = (CitySuggestion) selectedItem;
City city = selectedCitySuggestion.getCity();
Long id = city.getId();
}
});
Keep the reference from city name to id in a Map<String, Integer> and then look the ID up there before you save it.