DB4o update vs insert - persistence

Assuming you are using DB4O with the standard configuration and out-of-the-box - meaning, you are using DB4O's standard internal id scheme, as per below**.
First, as an assumption, when updating or inserting an object into the database, the programmer only has one option, to call "objectContainer.store(object)".
Now, how does DB4O know whether to update an existing object in the DB, or to insert an entirely new one? My guess is that DB4O looks to see if the internal id of the object is not null.
However, I could also see the possibility that the burden is on the programmer to first pull the object from the DB, then update it. So my question is, how can we reliably update an object in a DB4O database without first pulling it into Java memory?
*This DB4O article doesn't really answer my question
http://community.versant.com/Documentation/Reference/db4o-8.1/java/reference/Content/basics/update_concept.htm
**This is very informative:
http://community.versant.com/documentation/Reference/db4o-8.1/java/reference/Content/platform_specific_issues/disconnected_objects/comparison_of_ids.htm

db4o uses object identity in order to decide whether to insert / update objects (and AFAIK this is a central concept in db4o) so, even though it is possible, there's no easy way to accomplish that at db4o level (you probably have an abstraction for your data layer access; what you can do is to have two methods in this layer: insert and update; in update, before calling db4o.store(), you can check whether the object has already been loaded or not. This way, at least you can avoid mistakes that would cause object duplication in your db. If you do the same thing in insert you can be sure that you'll not update an object by mistake.
Hope this help.

Related

entity framework and database default values workaround

I have to decide about an important item and I need your help.
I'm facing an huge existing database with a lot of default values on nullable columns.
The team has to build a new MVC4 application on top of it (in fact it is a rewrite of old VB6 application).
I (as a consultant) have 'forced' the use of EF5 to get rid of all stored procedures and migrate to a more modern techology.
Now, after my research, it is clear to me that EF5 doesn't support database default values per default. This is why my inserted records are corrupt (they are inserted because the columns are nullable, but with NULL of course).
Some options came up like using the constructor technique, setting the default values in design on the edmx, or playing around with the xml of the edmx.
Despite, these methods are not usefull for us. Where the constructor technique looks ok for me, it is not feasible to do that for all tables in the DB. I also have a 'njet' from the technical person because he wants to maintain these values on 1 place. Same story for setting the default values in design. The database is also not in our scope (read: as less as possible changes to keep existing applications running).
At this point, I'm not sure it EF is the correct choice for our project.
Is somebody aware of (3th party) tools that can fill in the database default values automatically in the generated xml of the edmx file?
Is there som more info about how this xml is build and if there is a possiblity to interfere in the process?
Is there a good readon why these default values should not be taken? Is this going to change in a later release?
Are there other good practices that can be applied to that problem without having all values dupplicated or a massive workload?
Can I arrange something with my poco generator?
I realize there are already a lot of posts of this topic. Too bad, there is no suitable solution for me since we have already something existing and (with all respect) an old VB6 team that I have to convince.
Thanks for your feedback!

Any ideas on how SqlWorkflowInstanceStore could be made to work with a different schema?

Thank you in advance for any input or advice!
I am using WF4 in a large project that requires long running workflow persistence. For deployment consistency reasons, it would be helpful to use an alternate schema name for instance store objects. For example, System.Activities.DurableInstancing.InstanceTable would become DurableInstancing.InstanceTable, etc.
Updating the SQL scripts to accomplish this server-side is not difficult, but from what I can tell, there is no way to modify the default schema used by SqlWorkflowInstanceStore when generating commands. It appears the schema name is read from SqlWorkflowInstanceStoreConstants.DefaultSchema, which is a constant (as the name implies). SqlWorkflowInstanceStore is sealed and it seems to be quite a task to roll your own InstanceStore, so I'm reluctant to pursue that option.
Does anyone know of simpler way to do this that I might be missing? Also, I am aware that changing the schema name would add steps to applying future instance store updates, but can anyone foresee other potential problems?
I never tried that but as far as I know the SqlWorkflowInstanceStore only calls stored procedures. All of those need to be in the System.Activities.DurableInstancing DB scheme but you should be able to move the tables and views to another DB scheme.
Quite frankly I would probably never do that as that would mean I am no longer in a supported scenario and see no benefit. If for some reason you need to query the System.Activities.DurableInstancing tabled/view and because the way your app is set up that needs to be in another DB scheme I would just create views there pointing to the original tables.
Implementing your own InstanceStore isn't difficult. We were in a similar situation, we really didn't want to have two schemas, ours and the Workflow SQL. We implemented our own InstanceStore and it's about 280 lines of code. We had to add one table to our schema and a couple fields to existing tables.
I would encourage you to try implementing your own InstanceStore.

Is core data implementing data mapper pattern?

I know that core data should not be considered as ORM but it still offers the functionality that is similar to ORM. Just curious, is it implementing data mapper pattern? I know "The Data Mapper is a layer of software that separates the in-memory objects from the database. Its responsibility is to transfer data between the two and also to isolate them from each other." (Martin Fowler). IMHO context manager handles all SQL stuff into one transaction, so it's very performance wise design and IMHO core data might be considered implementing data mapper pattern.
One year latter, I will contribute with my two cents
I am not an ORM expert and just recently started something using a Data Mapper, but as a long time Core Data user I can say that no. The main objective of this pattern is having a clear cut of a domain object from all database related operations.
Once I start writing unit tests, the first thing I notice is that I must load a database, even if it is just some in memory store, but I do must load one. Also there are no mappers for each class, I have no control about how each relation is stored.
Core Data loads lots of meta information about your object graph and forces some structure to them. Although you can change the persistent store and bake something of your own, you will have lots of restrictions about how to do it, with a clear "relational" feeling to it.
The idea is good, we might say it is some variation of it. Something that I do love is that the save operation is done by the context, not the object itself. So there is some type of separation.
However look at those functions like "awakeFromFetch" or "didSave", both operations are related with the data store, not a plain domain object. A proper Data Mapper pattern would allow you to define those operations for each persistent store, not unified in a single object.
UPDATE:
Funny enough one day after my answer I had to deal with an old CoreData based project and must come back to improve this answer. To make things clear, I do consider that "seems like a pattern" is not enough. For example, implementation of the facade and adapter patterns is quite similar, but you name them differently depending on how you use them.
Is Core Data implementing data mapper?
I must say that my "not quite" should have been "definitely not!"
I have just been very angry because I needed to rename some fields and later add new ones. Although I do know quite well how auto-migrations work with Core Data I forgot how annoying these are.
How many times do you need some new field, rename something, experiment until you get it right.... and every single tiny change requires a full blown database migration? With Data Mappers this never happens because domain objects are perfectly decoupled. You only touch the database to catch up with the domain objects after you finish some new feature. Core Data forces you to bind at every single moment every single detail of your domain objects.
Boy, how sweet life was until I forgot that "tiny" annoyance of Core Data being the exact opposite of what you can achieve with data mappers.

Entity framework - what to do if SaveChanges fails and I don't want some changes to be made?

I think I'm running into a common problem:
I would like to try to insert an object to the database. If primary key is violated then I would like to abort the insert. (this is an example, the question really applies to any kind of error and any of the CRUD operations)
How can I discard changes made to EF context?
I can't afford recreating it every time something goes wrong.
PS. I know that perhaps I could check if everything is ok eg. by querying the db, but I don't like the idea. Db constraints are there for some reason and this way it's faster and I have to write less code.
You can detach inserted entity from ObjectContext. You can also use ObjectStateManager and its method GetObjectStateEntries. In ObjectStateEntry you can modify its state.
The problem is that you are not using technology in supposed way:
I can't afford recreating it every
time something goes wrong.
Sure you should because your code doesn't prevent such situations.
PS. I know that perhaps I could check
if everything is ok eg. by querying
the db, but I don't like the idea. Db
constraints are there for some reason
and this way it's faster and I have to
write less code.
Yes indeed you should check if everything is OK. Calling database to "validate" your data is something that DBAs really like (sarcasm). It is your responsibility to achieve the highest possible validity of your data before you call SaveChanges. I can imagine that many senior developers / team leaders would simply not pass your code through their code review. And btw. in the most cases it is not faster because of inter process or network communication.
Try using DbTransaction.
System.Data.Common.DbTransaction _tran = null;
_tran = _ent.Connection.BeginTransaction();
_tran .Commit (); //after SaveChanges();
and if theres an exception
do a rollback.
_tran.Rollback();

Entity Framework - avoiding another query

I have a requirement to only save data to a table in a database (I don't need to read it)
If the record already exists I want to update it otherwise I will add it.
It usually exists.
My entity context might already hold the object .. if it does I want to find it and use it again without causing it to refresh from the database when I 'find' it
i.e. The context holds a collection of entities (rows of a database) I want to find an entity in the collection and only want the context to go to the database if entity is not in the collection. I don't care about the current values of the entity .. I just want to update them.
Hope this is clear ..... thanks
I may not be quite seeing the question, but I believe your looking for some sort of caching mechanism, I know for work we use devForces IdeaBlade which does the trick, however I believe you can create a simple caching mechanism custom to you needs.
Link
The bits on caching will be helpful, if this doesnt help tell me and I can dig a little deeper.
I believe you need to use GetObjectByKey() instead of using an ObjectQuery I believe an ObjectQuery always hits the backend datastore whatever it may be.
More Info here http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.getobjectbykey.aspx