Can I get the object from the database, without knowing what type of the object is? - swift

I have the class GraphHandler. Inside of superclass I try to handle restoring the object that was last saved into the database. For this I'm using primaryKey.
The point is that a the time of restoring I don't know yet which type should I expect. So I tried with this:
let realm = ClientManager.cacheRealm()
realm.object(ofType: Object.self, forPrimaryKey: "uniqueid")
But I get the error:
Terminating app due to uncaught exception RLMException, reason: 'Object type RealmSwiftObject is not managed by the Realm. If using a custom objectClasses / objectTypes array in your configuration, add RealmSwiftObject to the list of objectClasses / objectTypes.'
Im trying to do it a way that the handler don't need to know in advance which type of object was saved last. What can solve this? I think that implementing generics won't do any good to it as I can't be changed on the fly.

By the time you call the function realm.object, the type of the object needs to be known, since using this function, realm is only searching for objects of a specific type. Moreover, the type of primary key can be different as well, hence the type of object you are looking for needs to be known before querying realm.
Querying all types and filtering afterwards is only not an option at the moment, since Result can only store a single type of objects. However, if you really need to query all types using a single query to get the last database entry regardless of what class it had, have a look at this comment on a related GitHub issue, where Realm engineers give some workaround for the issue.
Another workaround you could try is the following: create a TimeStamps class, which is managed by Realm, has only a single entry in Realm and which has a one-to-one relation to each of your other Realm classes. The object on the other side of the one-to-one relation would always be the object that you added the last time to Realm of that specific class. With this approach, if you are looking for the latest object added to realm, you can use a simple query that retrieves the only TimeStamps object you have and you can filter for the object added last by filtering the one-to-one relations TimeStamps have. Of course for this to work, you need to associate the creation date of your objects with the relationships you are storing in your TimeStamps object and update these relationships in each of your write transactions.

Related

I want to store a collection of small non-primitive types using Entity Framework and Cosmos DB

Using Entity Framework and Cosmos DB, I want to store an object that has a property of type HashSet<Guid>. I got an exception message that Guid is not a primitive type and collections of it cannot be mapped. OK, I wrote a pair of ValueConverter/ValueComparer for HashSet<Guid>, but that feels... not very elegant. Is there a better way to do it? I also have a collection of small custom objects that can be stored as a string with a certain syntax. I tried setting a converter/comparer in the ConfigureConventions but it didn't work either. Is it possible to store an ICollection<MySmallType> as a collection of strings? Thank you!

Kotlin immutable entities changing unexpectedly when using it with JPA

In our project we are using kotlin with JPA. All of our entities are immutable so, it is not possible to set fields of our entities directly. You have to create a new instance by using the copy method. If you want these changes to be reflected to database, you must persist this newly created entity with an explicit function call.
In the beginning, this approach looks perfect to us. However, nowadays we are having some problems like some of our instances are changing unexpectedly in the memory.
val instance1 = repository.findById(entityId)
repository.save(instance1.copy(deletedAt = Instant.now()))
..
..
assertNull(instance1.deletedAt())
In the code snipped above, instance1 is retrieved from database and its deletedAt field is set with copy method and the new instance which is created with this copy method is passed to save method of the repository. We don't set any field of instance1, we create a new instance to do these changes. However, the result on assert line is unexpectedly not-null.
It seems, There is a confliction on JPA persistence context (first level cache) and kotlin's immutable and copy method logic.
Is anyone facing this problem or any suggestion or best practices when using JPA and immutable Kotlin entities?
I suspect the problem is that you're ignoring the return value from save().  Its docs say:
Saves a given entity. Use the returned instance for further operations as the save operation might have changed the entity instance completely.
But you're not doing that; you're instead continuing to use the original instance which (as that says) may have changed.
Instead, store the return value from save(), and use that thereafter.  (Either by making instance1 a var, or creating a new val and not referring to instance1 afterward.)
(This isn't a Kotlin-specific problem, and is exactly the same in Java.  JPA , Spring, &c work their magic by futzing with the bytecode, so can do things your code can't — such as changing immutable values.  Most of the time you can ignore it, but this case makes it obvious.)
Immutable types are not compatible on how JPA works.
JPA works around the concept of UnitOfWork, which mean objects retrieved from the database lives in a PersistedContext (1st level cache) and they get discarded once the EntityManager is closed (on a web application at the end of the HTTP request).
When using the copy method in an entity you just retrieved from the database, the copied object is considered detached from the current session meaning that changes on it cannot be tracked by JPA and the underlying implememtation (Hibernate / EclipseLink) have hard time figuring out which SQL statement needs to be fired (Insert/Update/Delete ????)
Things got way more complex when you have complex object graph with OneToMany associations and cascading options.
So my recommendation is unfortunately is to avoid Immutable types when using JPA.

What does Realm Database save? Only variables or functions as well?

In this simple class:
class Simple: Object{
#objc var name: String = ""
func doSomething(){}
}
When I save this into Realm, what does get saved? The variable only or the function as well? The reason I am asking this, is because when I got a lot of Simple objects, I do not want to save the functions ofcourse. The objects would get bigger causing a negative influence on performance.
The variable. It creates a 'column' named "name". Check the realm docs.
Also if you have a lot of data and you would like to browse it you could do it with this Realm Browser where you can see clearly your realm database structure.
You should read through the official documentation and especially the part about supported model properties, which clearly mentions what you can persist in Realm objects.
You can only save properties of certain supported types (Int, String, etc.) or references to other Realm objects (as one-to-to, one-to-many or inverse relations), but you cannot save function references and it wouldn't make sense anyways.
You can add ignored properties and functions to your Realm model classes, but they will only exist in memory, they won't be saved to Realm. For functions this is all you actually need, it wouldn't make any sense to save a function to local storage.
Also, your current model is flawed as your name property is missing the dynamic keyword in its declaration and hence it cannot be treated as a Realm property.

Breeze JS Adding a static Lookup dictionary to Metadata

One of my domain models has an Enum property that I like to create a dropdown box for, but the EFContextProvide Metadata function doesn't automatically import the Enum Entity Type for me to access it, so I created a static dictionay of that I like to add to the Metadata Mapping, acting as a lookup table. How can I add Enum entity type, so I can call:
breeze.EntityManager.createEntity(myEnum,...)
right now, I get the following error:
Error: Unable to locate an 'Type' by the name: myEnum
Any suggestion?
UPDATE: (I just added the enumType info of the Metadata function call)
"enumType":{"name":"Plugins","isFlags":"false","underlyingType":"Int32","member":["name":"Custom","value":"0"},{"name":"PluginOfTypeA","value":"1"},{"name":"PluginOfTypeB","value":"2"}]}
Thanks #Jay for your response, I was set in the right direction. Here is what I can say about dealing with Enum:
I created a lookup list on the server that I can separately call, to populate the dropdown list. I have a regular array that I initialize on the success promise of the results, list this data.results[0].myEnumLookup and then on the Viewmodel, I access that property and set in to the ko.observableArray() so I can refer to it in my View. Make sure you set the value: property of the select tag, to the value of item.
But the problem with doing it this way was that at the Save time, it wasn't reading Enum value and it was treating it as just text, so it was failing, so
More robust solution:
In our application we happen to really benefit from having an Enum and their pre-compile value, since we are using those Enum Domain models in other POCO projects, so I ended creating an EF DbSet and proper table that will be populated with all of my Enums values and I can save them into the DB, so now we have the list of items in DB, and I created a single level of inheritance for Enums, so in my controller, I get a IQueryable method that will get all of those Enums, and in the breeze application, in my config file, I define the types of enums, and then I will populate lists of items based on different types in my config, so I can refer to it in my view and binding it to the ko.observableArray(). Also in my original class, I no longer refer to the Enum, I will create MyEnumId as well as virtual MyEnum property that will do the mapping automatically in my EF5 setup.
Lesson I learned, even though Enum in .NET4.5 & EF5 is possible to store and read back, but it's not very practical when it comes to SPA front-end technologies, so I prefer having the integer value, and just manage the enums outside of it.
Not entirely sure I understand the question. By 'Enum entity type' do you mean an 'EntityType' that only has a fixed number of possible instances? If so, you can simply query the entire collection of these entity/instances onto the client and add them directly into your static dictionary. Since, the collection is conceptually immutable, you can query this at the beginning of you session. Further, you should NEVER need to create an instance of any of these 'entity enums' because you can always extract them from your dictionary.
But maybe I'm not understanding your question.

Inheritance problems with Entity Framework (table per type)

For part of the project I'm currently working on, I have a set of four tables for syndicatable actions. One table is the abstract base for the other three, and each table is represented in my EF model like so:
EF Model -- Actions http://chris.charabaruk.com/system/files/images/EF+Model+Actions.png
There are two problems that I'm currently facing with this, however. The first problem is that Actor (a reference to a User) and Subject (a reference to an entity of the class associated with each type of action) are null in my subclasses, despite the associated database columns holding valid keys to rows in their associated tables. While I can get the keys via ActorReference and SubjectReference this of course requires setting up a new EF context and querying it for the referenced objects (as FooReference.Value is also null).
The second problem is that the reciprocal end of the relationship between the concrete action classes and their related entity classes always turn up nothing. For example, Task.RelatedActions, which should give me all TaskAction objects where Subject refers to the particular task object on which RelatedActions is called, is entirely devoid of objects. Again, valid rows exist in the database, Entity Framework just isn't putting them in objects and handing them to me.
Anyone know what it is I'm doing wrong, and what I should do to make it work?
Update: Seems that none of the relationship properties are working in my entity model any more, at all. WTF...
I think the issue you are experiencing here is that by default the EF does not automatically load related entities. If you load an entity, the collection or reference to related entities will be empty unless you do one of the following things:
1) Use eager loading in order to retrieve your main entity and your related entity in a single query. To do this, modify your query by adding a call to the Include method. In your sample above, you might use the following query:
from a in context.Actions.Include("Actor") select a
This would retrieve each of the actions with the related Actor method.
2) Use explicit lazy loading to retrieve the related entity when you need it:
action1.ActorReference.Load()
In the version of the EF which will ship with .Net 4.0, you will also have the following additional option:
3) Turn on implicit lazy loading so that related entities will automatically be retrieved when you reference the navigation property.
Danny