I am trying to break a relationship on an object but can’t find the proper documentation for it, and all the similar questions in this forum seem to be different circumstances.
In the iOS SDK, how do I remove a 1:1 relationship from an object? I don’t want to delete the objects, simply break the relationship.
I attempted to simply set the relationship to null, but that doesn’t work and I know that is because backendless interprets that as me not wanting to update that field. But even when I attempt to save this object I get the following Fault:
“Custom business logic execution has been terminated because it did not complete in permitted time - 5 seconds”
Here is my attempt to break the relationship:
ticket.associate = nil;
id<IDataStore> ticketDataStore = [backendless.persistenceService of:[Ticket class]];
[ticketDataStore save:ticket responder:handler];
The custom business logic event handler that the fault is referring to is a synchronous afterFind event handler on the Ticket class:
BackendlessDataQuery ticketQuery = new BackendlessDataQuery("objectId='" + ticket.getObjectId() + "'");
QueryOptions options = new QueryOptions();
options.addRelated("store");
ticketQuery.setQueryOptions(options);
BackendlessCollection<Ticket> ticketResponse = Backendless.Persistence.of(Ticket.class).find(ticketQuery);
if (ticketResponse.getData() != null && ticketResponse.getData().size() > 0) {
String channel = "requests." + ticketResponse.getData().get(0).getStore().getObjectId().replace("-", "_");
MessageStatus status = Backendless.Messaging.publish(channel, "update");
}
The second question (execution time) seems simpler. You need to make sure it is executed in less than 5 second (otherwise, you’d need to purchase a function pack to extend the execution time to 20 seconds). One optimization I can see is setting the pageSize parameter to 1, since you’re using only one object in the response. This will run the find query faster.
As for breaking a relationship, setting property to null should work, but only if the original object was retrieved with that relation initialized. Simply loading an object without relations, then setting a related property to null and saving the object, will not do anything.
Regards,
Mark
Hi Mark, I set the pageSize to 1 and still get the 5 second issue most of the time. I have no problem paying for the 20sec package but I would actually rather the logic not take so long. I made the business logic asynchronous and it seems to never throw that error anymore. But even when it was synchronous, the single query that I am doing and publishing a message don’t seem like excessive operations.
Is it possible Backendless is receiving a lot of traffic lately? Is there anyway to pay for a package that may boost the speed of requests? I’ve noticed that some things such as simply saving an object can take ~3 seconds.
As for breaking the relationship, I tried both setting the property to ‘nil’ and to ‘[NSNull null]’ and neither seem to have any effect. I checked the function and the object does have an associate field populated which was returned from the server through requesting the relation.
Thanks,
Matthew
Hi Matthew,
You’re welcome to benchmark the queries in a standalone Java app to see how long these operations take. 3 seconds for simple object persistence seems excessive, however, if you’re saving a complex object closure, it may be justified.
We do operate an additional cloud for customers who purchased the Managed Backendless service. This is where we provide guaranteed uptime, SLAs backups as well as some other benefits. If you’re interested, please contact our sales at sales@backendless.com.
Regarding breaking relations, I will ask our iOS guys to see if they can reproduce the problem (I just tried with Android and it works).
Regards,
Mark
Ok fair enough. What about the following scenario, would it be considered complex?
I have an object, Ticket, with the following schema:
name (STRING
associate (1:1 Relation (Users))
type (INT)
email (STRING)
status (INT)
actions (1:N Relation (Action))
customer (1:1 Relation (Users))
fixture (1:1 Relation (Users))
store (1:1 Relation (Store))
I’m making a PUT request to “https://api.backendless.com/v1/data/Ticket/<OBJECT-ID>” using Postman with the following body:
{
"associate": {"___class":"Users", "objectId":"E9CAFB94-3294-FF20-FF3B-999B4F0DA900"}
}
Here are my timing results after 10 tests:
4748 ms
4162 ms
3561 ms
249 ms
1996 ms
3710 ms
167 ms
4270 ms
3682 ms
5638 ms
A speed test shows the following (ran a couple times to ensure it was consistent):
Ping: 2
Upload: 38+ mbps
Download: 44+ mbps
FYI, I sent an email to inquire about the managed service.
Thanks. Could you re-run your test with the following body and post the result?:
{
“name”:“foo”
}
Looks like Postman adds a lot of overhead to these numbers. Here’s a video I just recorded with almost identical test. The number I get (as you will see at the end of the video range from 107ms to 1630ms)
https://monosnap.com/file/XajJ0LY47XwkGBAcKmFnpPK7At8TMS
I tried the same steps as you with the same results. We’ll let you know if we experience any further issues.
Thanks for looking into this for me.
Would be great if you could still let me know about the iOS relationship question. Thanks!
Any update on how to break a relationship in Objective C?
Hi Matthew, it is in the queue. We will post an update as soon as a developer looks into it.
Hi Matthew,
I cannot reproduce this issue.
I implement simple sample with two classes (In Swift, but I think it doesn’t matter):
class Address : NSObject {
var street : NSString?
var city: NSString?
var state : NSString?
}
class Contact : NSObject {
var objectId : String?
var name : String?
var age : Int = 0
var phone : String?
var title : String?
var homeAddress : Address?
var weight : Double = 0.0
}
and a method, which saves Contact object with 1:1 relation to Address object, then removes it and updates Contact object:
func removeOneToOneRelation() {
let address = Address()
address.street = "555 Commerce St"
address.city = "Los Angeles"
address.state = "CA"
var contact = Contact()
contact.name = "Bob"
contact.phone = "555-222-333"
contact.age = 37
contact.title = "Vice President"
contact.homeAddress = address
let dataStore = backendless.data.of(Contact.ofClass())
var error: Fault?
contact = dataStore.save(contact, fault: &error) as! Contact
if error == nil {
print("Contact has been saved: homeAddress = \(contact.homeAddress)")
}
else {
print("Server reported an error (1): \(error)")
}
// remove 1:1 relation
contact.homeAddress = nil
dataStore.save(
contact,
response: { (result: AnyObject!) -> Void in
let obj = result as! Contact
print("Contact has been updated: homeAddress = \(obj.homeAddress)")
},
error: { (fault: Fault!) -> Void in
print("Server reported an error (2): \(fault)")
})
}
Here is a log:
http://support.backendless.com/public/attachments/ef46e07fa38aef70faa0f1940b518d2f.png</img>
As you can see, 1:1 relation is created after first ‘save’, then it is removed after second ‘save’ (== ‘update’).
Please pay your attention on line 18: the result of first ‘save’ call is saved in ‘contact’ var, and all following acts are made with this object, not with “original” ‘contact’.
So, it is possible to remove an existing 1:1 relation.
Could you provide your sample code demonstrating the problem?
Regards,
Slava