db4o Developer Community
Developer Community db4o open source object database, native to Java and .NET
Register   |  Login
  Search
  • Forums
  • Documentation
  • Resources
  • Downloads
  • Blogs
  • About
Unanswered Active Topics Forums
Forums > English Forums > db4o User Forum
Unique IDs in db4o
Last Post 05 Sep 2006 10:26 AM by Goran. 10 Replies.
AddThis - Bookmarking and Sharing Button Printer Friendly
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
mrshrinkray
New Member
New Member
mrshrinkray

--
29 Aug 2006 04:25 PM  
I'm having a problem updating items in db4o, without having the primary key ID which I'm use to in databases. For example, I have a class:

class Company
{
public string Name;
public string Address;
}

If I have 2 companies with the same name, it updates them both. The obvious solution is to add an ID field which is randomly generated integer.

But I'm wondering, is there a more optimised alternative to this? Does db4o offer a unique ID generating method for a class or similar? Someway of differentiating?
jleotta
New Member
New Member
jleotta

--
29 Aug 2006 04:50 PM  
If you query for company by name and they both have the same name the objectset should contain both companies.  I dont believe there is any way to update them both without selecting each and updating them calling set and commit.  How would you look up this company in a phone book?  How would you know the primary key at runtime? 
Albert Kwan
New Member
New Member
Albert Kwan

--
29 Aug 2006 04:50 PM  
I would recommend you to take a look at the tutorial chapter 15

15. IDs


The db4o team recommends, not to use object IDs where this is not necessary. db4o keeps track of object identities in a transparent way, by identifying "known" objects on updates. The reference system also makes sure that every persistent object is instantiated only once, when a graph of objects is retrieved from the database, no matter which access path is chosen. If an object is accessed by multiple queries or by multiple navigation access paths, db4o will always return the one single object, helping you to put your object graph together exactly the same way as it was when it was stored, without having to use IDs.

The use of IDs does make sense when object and database are disconnected, for instance in stateless applications.

db4o provides two types of ID systems.


15.1. Internal IDs

The internal db4o ID is a physical pointer into the database with only one indirection in the file to the actual object so it is the fastest external access to an object db4o provides. The internal ID of an object is available with
objectContainer.ext().getID(object);

To get an object for an internal ID use
objectContainer.ext().getByID(id);

Note that #getByID() does not activate objects. If you want to work with objects that you get with #getByID(), your code would have to make sure the object is activated by calling
objectContainer.activate(object, depth);

db4o assigns internal IDs to any stored first class object. These internal IDs are guaranteed to be unique within one ObjectContainer/ObjectServer and they will stay the same for every object when an ObjectContainer/ObjectServer is closed and reopened. Internal IDs will change when an object is moved from one ObjectContainer to another, as it happens during Defragment .


15.2. Unique Universal IDs (UUIDs)

For long term external references and to identify an object even after it has been copied or moved to another ObjectContainer, db4o supplies UUIDs. These UUIDs are not generated by default, since they occupy some space and consume some performance for maintaining their index. UUIDs can be turned on globally or for individual classes:
Db4o.configure().generateUUIDs(Integer.MAX_VALUE); <br />
            Db4o.configure().objectClass(typeof(Foo)).generateUUIDs(true);

The respective methods for working with UUIDs are:
ExtObjectContainer#getObjectInfo(Object) <br />
            ObjectInfo#getUUID();<br />
            ExtObjectContainer#getByUUID(Db4oUUID);

vinayaka.bdvt
New Member
New Member
vinayaka.bdvt

--
29 Aug 2006 05:18 PM  

mrshrinkray:
If I have 2 companies with the same name, it updates them both. The obvious solution is to add an ID field which is randomly generated integer.

  Another way of identifying the Object is UUID , provieded by db4o.

For more explanation about UUID please read chapter 15 in the tutorial.

Also please see the Carl explanation for getting the UUID in the object itself. Based on UUID you can differentiate the objects.

http://developer.db4o.com/forums/thread/21897.aspx

Regards

Vinayak

 

treeder
New Member
New Member
treeder

--
29 Aug 2006 10:15 PM  
Check out this blog post for a way to do it using External Callbacks: http://developer.db4o.com/blogs/pro...27745.aspx
mrshrinkray
New Member
New Member
mrshrinkray

--
30 Aug 2006 12:52 PM  
This is a .NET website application, so it would be quite memory-intensive to pass the object(s) in the viewstate in order to avoid using IDs.

The tutorial sums this up anyway, as web apps are stateless, even with Microsoft trying to send the state via POST in the viewstate which I have found very slow for larger websites, but works great for small crud apps.

"The use of IDs does make sense when object and database are disconnected, for instance in stateless applications."
Goran
Basic Member
Basic Member
Posts:295
Goran

--
30 Aug 2006 01:17 PM  
mrshrinkray:
This is a .NET website application, so it would be quite memory-intensive to pass the object(s) in the viewstate in order to avoid using IDs.


It wouldn't work anyway. When objects are deserialized from viewstate they hold no connection to your db4o. There's no way for db4o to identitfy this object so it will be treated as a new object.

Goran
Eric Falsken
Advanced Member
Advanced Member
Posts:924
Eric Falsken

--
02 Sep 2006 01:43 PM  

In .NET, Use the ObjectDataSource. Handle the ObjectOnCreating event.

Dino Esposito (on the ASP.NET team) had a great blog entry about how to use the ObjectDataSource properly: http://weblogs.asp.net/despos/archive/2006/04/27/444188.aspx

The key is to pass only the ID (or db4o UUID) of the desired object(s). Then to use the ObjectDataSource events to properly retrieve a working copy of the object (in db4o, this object would still be in memory in the weak-reference cache, so retrieval is almost nothing) and to store it again (a single line, using db4o).

Goran
Basic Member
Basic Member
Posts:295
Goran

--
02 Sep 2006 10:29 PM  
Eric Falsken:

Then to use the ObjectDataSource events to properly retrieve a working copy of the object



Why not just using ObjectContainer.Ext().Bind(object, id)?

Goran
Eric Falsken
Advanced Member
Advanced Member
Posts:924
Eric Falsken

--
05 Sep 2006 08:04 AM  

Calling Bind() will cause any other instance of the object in memory to be unbound. So if another thread is working with the same object from the same objectContainer, you will break the binding.

Calling GetByID(long) is also quite a bit faster than deserializing. And it dosn't cut down on any code. You store the ID to ViewState/ControlState and you have a property getter to retrieve your desired object. If you use the ObjectDataSource, then you don't even have to do your field-to-property mapping. If you roll-your-own via serializing your object to viewstate, then you have to do your own field-to-property mapping in addition to making sure that your object is safely serializable. A hell of a lot of work. Not to mention the MUCH reduced size of the ViewState.

ObjectDataSource works VERY well and will speed up your development and run faster. And don't forget about Atlas!

Goran
Basic Member
Basic Member
Posts:295
Goran

--
05 Sep 2006 10:26 AM  
Hi!

Thank you for the info.

In my case I am using ObjectDataSource to populate a gridView. On update event is called after postback so the identity of my object is not the same as the one that was bound to the gridView. If I simply store my object it will create another copy of the object in the db and not update the existing one. That is why I use bind method to make sure db knows which object I am updating.

So currently:
1. My web control passes the modified BusinessObject to ObjectDataSource's Update method.
2. ODS passes the modified BusinessObject  to a DataAdapter's Update method.
3. DA's Update method binds the object through his id field, and the sets the object.

With your suggestion step 3. would change into:
3.1. Get original object from db by using modified object id.
3.2. Pass modifications to original object.
3.3. Set original object.

Am I correct?

Goran
You are not authorized to post a reply.
Forums > English Forums > db4o User Forum

Active Forums 4.2
Close
Copyright ©2000-2010 by Versant Corp.
Privacy Policy