I have a core data entity 'Person'. I need to customise the section index title and so I thought of creating transient attribute the separate the data into some specific section based on my own logic. But, while I create the fetch request with fetchedResultsController, and keep this transient attribute 'sectionNameKeyPath' to initialize the fetchedResultsController sectionNameKeyPath. And so, I had to make this as a key to first sort descriptor. But, this crashes the applications. Isn't it possible to use transient attributes as sectionNameKeyPath in fetchedResultsController
My crash log is.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath sectionNameKeyPath not found in entity <NSSQLEntity Person id=1>'
You can use a transient attribute as sectionNameKeyPath for a fetched results controller. But you cannot use a transient attribute in the sort descriptor. For a SQLite based Core Data store, only non-transient attributes can be used in sort descriptors.
This is documented in Fetch Predicates and Sort Descriptors in the "Core Data Programming Guide":
The SQL store, on the other hand, compiles the predicate and sort
descriptors to SQL and evaluates the result in the database itself.
This is done primarily for performance, but it means that evaluation
happens in a non-Cocoa environment, and so sort descriptors (or
predicates) that rely on Cocoa cannot work. The supported sort
selectors are ...
In addition you cannot sort on transient properties using the SQLite store.
But the first sort descriptor need not be the same as the sectionNameKeyPath, see the documentation of initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:
sectionNameKeyPath
...
If this key path is not the same as that specified by the
first sort descriptor in fetchRequest, they must generate the same
relative orderings. For example, the first sort descriptor in
fetchRequest might specify the key for a persistent property;
sectionNameKeyPath might specify a key for a transient property
derived from the persistent property.
The DateSectionTitles sample code from the iOS Developer Library demonstrates how this works.
Related
Is there a way to use a 'transient' field or something like that and in some way sort accordingly with a NSFetchedResultsController. I want to do the following:
I have location of places in a database. When a person opens the list, I want to show the nearest place on top, an then sort accordingly to distance. But clearly,this depends on the users location, so I cannot use a static field. I was hoping to use a transient field, as you can use for the section headers.
Is there anybody who can give a solution or workaround for this situation?
You cannot use a transient property in a fetch request for a SQlite base Core Data store.
See Fetching Managed Objects in the "Core Data Programming Guide":
You cannot fetch using a predicate based on transient properties
(although you can use transient properties to filter in memory
yourself). ... To summarize, though, if you execute a fetch directly, you should
typically not add Objective-C-based predicates or sort descriptors to
the fetch request. Instead you should apply these to the results of
the fetch.
You can use a transient property for sectionNameKeyPath, but even then you need a first sort descriptor for the sections that is based on a persistent attribute.
So the only workaround is probably to fetch all objects and then sort the fetched array. But then of course you don't have the advantages of a fetched results controller anymore.
How do I control which fields get serialized in Axis2? I have some fields (really getter/setter pairs) that I don't want exposed to the client. Also, some are coming across as nullable (e.g. someIntSpecified properties are created) where I want them.
I think there is unfortunately no annotation to exclude attributes from getting serialized.
I think you will need to create Data Transport Objects (DTOs). Otherwise you won't have a clean separation between your core business objects and the objects that you expose as API.
I've having an issue where CoreData is unable to fulfill a fault on an object. I assume it's because the object has been deleted and now CoreData is trying to access a property in some context and can't fault it in. To resolve this I attempted to call setRelationshipKeyPathsForPrefetching and pass it the relationships that I want to have prefetched.
Example, I have an Entity A, and it has a to-many relationship to Entity B, but at some point while I'm accessing properties on Entity B, Entity B is deleted in another context and now a fault can't be fulfilled.
[request setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObjects:#"listOfBs", nil]];
I thought that if I did this, it would prefetch Entity B so that I can call its properties safely but this doesn't seem to be the case.
EDIT: I can't seem to find any info about this but it must be a fairly common problem. If some context has a managed object that is deleted in another context, it should have some way to safely figure out that the object no longer exists rather than just crashing
EDIT 2: I don't think CoreData is properly acknowledging my prefetch request. If I call setRelationshipKeyPathsForPrefetching than the objects that are returned should be faulted in yet even in the case where I don't have an error, I can simply print out the object that get returned and see that they are faulted. Does CoreData not prefetch objects in to-many relationships?
EDIT 3: Ok so perhaps the relationships themselves are prefetched but the properties on the prefetched items are not faulted in. So if I have Entity A and I want to prefetch all of the B's associated with A, I use setRelationshipKeyPathsForPrefetching but all of the properties of the B's are not faulted in.
Figured out a solution. Core Data doesn't allow atomic fetches from the database so if something after prefetching the relationships, Core Data would throw an error. Prefetching the relationships does just that, prefetches the relationships. But not the data. The solution was to use a try/catch and refresh the object on an exception.
I have an exception occurring when saving changes to a self tracking entity:
AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
I believe the problem is addressed in other questions such as: Self Tracking Entities - AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager
My question is what is the best way to debug this problem both in development and production. Is there any further information that can be caught/accessed which will detail which entities or the entity types which are causing the exception.
If not will I have to write something to traverse the object graph looking for duplicate keys referencing different objects? If so does anyone have experience of this?
Further info:
My scenario involves the following - the client retrieves an entity via a WCF service which contains collections of further entities all with various FKs to other entities. These FK relationships are all included in the linq query so we have a complete object graph.
The views in the client use previously fetched entities for static data such as lookup tables for performance. If we have say a Customer object with a FK to User this will be loaded when retrieved from the service. If we now add another entity to the object graph e.g. Order and set a User property on this object which has the same Id as in the Customer object but the entity was retrieved at a different point and therefore using a different ObjectContext (i.e. the objects have the same Id but are not the same instance of the object) I get this error.
The link to the other question demonstrates ways to avoid this but I am looking to find more information about which entities are causing the problem so I can track down the error.
This usually happens if you try to AcceptChanges on the context which was used to load entities before - use new empty context for accepting changes. AcceptChanges cannot be used when any entity from STE is already loaded in the context - that is limitation of current STE implementation (but it can probably be removed if you rewrite the template).
As I know there are no detailed exceptions for this kind of problems. For debugging STEs check their generated code. You have whole STE code available so you can browse change tracker and search for entities but it will not be easy.
I'm actually not sure if it is even possible to define duplicates on the client but let's suppose that it is. If you have the control over client code the best way is diagnose the client code. Add some logging and find the reason for duplications. Then remove the duplication because fixing the issue on the client will be easier then fixing the issue on the service. If you don't have control over the client I would say that it is a problem of incorrect data passed to your client and let client's developers to fix it.
I had been banging my head against this problem for more hours than I cared to admit. Finally found that the cause of the problem was that I had listened to the ReSharper hint to make my
context provider static. since that occurred with a variety of other changes, I didn't think to check it as being the culprit. But in my case, that was the issue.
I am new to programming (6 weeks now). i am reading a lot of books, sites and blogs right now and i learn something new every day.
Right now i am using coldfusion (job). I have read many of the oop and cf related articles on the web and i am planning to get into mxunit next and after that to look at some frameworks.
One thing bothers me and i am not able to find a satisfactory answer. Beans are sometimes described as DataTransferObjects, they hold Data from one or many sources.
What is the recommended practice to handle this data?
Should i use a separate Object that reads the data, mutates it and than writes it back to the bean, so that the bean is just a storage for data (accessible through getters) or should i implement the methods to manipulate the data in the bean.
I see two options.
1. The bean is only storage, other objects have to do something with its data.
2. The bean is storage and logic, other objects tell it to do something with its data.
The second option seems to me to adhere more to encapsulation while the first seems to be the way that beans are used.
I am sure both options fit someones need and are recommended in a specific context but what is recommended in general, especially when someone does not know enough about the greater application picture and is a beginner?
Example:
I have created a bean that holds an Item from a database with the item id, a name, and an 1d-array. Every array element is a struct that holds a user with its id, its name and its amount of the item. Through a getter i output the data in a table in which i can also change the amount for each user or check a user for deletion from this item.
Where do i put the logic to handle the application users input?
Do i tell the bean to change its array according to the user input?
Or do i create an object that changes the array and writes that new array into the bean?
(All database access (CreateReadUpdateDelete) is handled through a DataAccessObject that gets the bean as an argument. The DAO also contains a gateway method to read more than one record from the database. I use this method to get a table of items, which i can click to create the bean and its data.)
You're observing something known as "anemic domain model". Yes, it's very common, and no, it's not good OO design. Generally, logic should be with the data it operates on.
However, there's also the matter of separation of concerns - you don't want to stuff everything into the domain model. For example, database access is often considered a technically separate layer and not something the domain models themselves should be doing - it seems you already have that separated. What exactly should and should not be part of the domain model depends on the concrete case - good design can't really be expressed in absolute rules.
Another concern is models that get transferred over the network, e.g. between an app server and a web frontend. You want these to contain only the data itself to reduce badnwidth usage and latency. But that doesn't mean they can't contain logic, since methods are not part of the serialized objects. Derived fields and caches are - but they can usually be marked as transient in some way so that they are not transferred.
Your bean should contain both your data and logic.
Data Transfer Objects are used to transfer objects over the network, such as from ColdFusion to a Flex application in the browser. DTOs only contain relevant fields of an object's data.
Where possible you should try to minimise exposing the internal implementation of your bean, (such as the array of user structs) to other objects. To change the array you should just call mutator functions directly on your bean, such as yourBean.addUser(user) which appends the user struct to the internal array.
No need to create a separate DAO with a composed Gateway object for your data access. Just put all of your database access methods (CRUD plus table queries) into a single Gateway object.