Forums

Get More Support

Here for you 24/7

learn more
VOD Free SDK

Start Building your Engine Now

Download Now
VOD Extranet

Access to patches, license management,
tech docs and more for existing VOD customers.

Learn More
Adding a UniqueFieldValueConstraint when the ObjectContainer is already open?
Last Post 25 May 2009 01:14 PM by Maik Jablonski. 14 Replies.
AddThis - Bookmarking and Sharing Button Printer Friendly
  •  
  •  
  •  
  •  
  •  
Sort:
PrevPrev NextNext
You are not authorized to post a reply.
Author Messages
c.cerbo@gmail.com
New Member
New Member
Posts: 8


--
25 May 2009 01:48 AM

    Hello,

    I know that the UniqueFieldValueConstraints should be set in the configuration before opening a new ObjectContainer, but I'd like to know if it's possibile to update the configuration when the ObjectContainer is already open.

    I need this because I use db4o with DataNucleus (JDO Spec) and this constraint may not always be set a the begining.

    For more details see here: http://www.datanucleus.org/servlet/...tion_16668

    kostia
    mtz1406
    New Member
    New Member
    Posts: 31


    --
    25 May 2009 05:23 AM

    you can access to the configuration of an opened ObjectContaner like this:

    ObjectContainer db = Db4o.openFile("myDB.Yap",configuration);

    db.ext().configure().add( configurationItem);

     for more information look at The API for db4o

    I hope that helpful.

     

    c.cerbo@gmail.com
    New Member
    New Member
    Posts: 8


    --
    25 May 2009 06:33 AM

    Thanks for your replay, but I've already tryed and it takes no effect.

    This is my test code (I use the new API):

    ObjectContainer db = Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(), DB_PATH);
    EmbeddedConfiguration config = new EmbeddedConfigurationImpl(db.ext().configure());
    CommonConfiguration common = config.common();
    common.objectClass(Item.class).objectField("id").indexed(true);
    common.add(new UniqueFieldValueConstraint(Item.class, "id"));
    
    db.store(new Item(1L));
    db.store(new Item(1L));
    db.close();
    

    but no UniqueFieldValueConstraintViolationException is thrown.

    kostia
    mtz1406
    New Member
    New Member
    Posts: 31


    --
    25 May 2009 07:24 AM
    you create new EmbdedConfiguration at :
    EmbeddedConfiguration config = new EmbeddedConfigurationImpl(db.ext().configure());
    and this is mistake.
    use the configuration immediately like this:
     db.ext().configure().common().objectClass(Item.class).objectField("id").indexed(true);
    db.ext().configure().common().add(new UniqueFieldValueConstraint(Item.class, "id"));
    Note that: I think you use db4o 7.9 and I am writing this reply with out check the API for the 7.9 but I depend on your code. 
     
    c.cerbo@gmail.com
    New Member
    New Member
    Posts: 8


    --
    25 May 2009 10:35 AM

    No chance: it doesn't work.

    I post my complete testcase (db4o 7.9):

    public class UniqueFieldTest {
    	static private final String DB_PATH = "/tmp/db40.db";
    	private EmbeddedConfiguration config() {
    		EmbeddedConfiguration config = Db4oEmbedded.newConfiguration();
    		CommonConfiguration common = config.common();
    		common.objectClass(Item.class).objectField("id").indexed(true);
    		common.add(new UniqueFieldValueConstraint(Item.class, "id"));
    		return config;
    	}
    	/**
    	 * UniqueFieldValueConstraint set BEFORE to open the ObjectContainer
    	 */
    	@Test(expected = UniqueFieldValueConstraintViolationException.class)
    	public void testUniqueFieldValueConstraintBefore() throws Exception {
    		new File(DB_PATH).delete();
    		ObjectContainer db = Db4oEmbedded.openFile(config(), DB_PATH);
    		db.store(new Item(1L));
    		db.store(new Item(1L));
    		db.close();
    	}
    	/**
    	 * UniqueFieldValueConstraint set AFTER to open the ObjectContainer
    	 */
    	@Test(expected = UniqueFieldValueConstraintViolationException.class)
    	public void testUniqueFieldValueConstraintAfter() throws Exception {
    		new File(DB_PATH).delete();
    		ObjectContainer db = Db4oEmbedded.openFile(Db4oEmbedded.newConfiguration(),
    				DB_PATH);
    		Configuration config = db.ext().configure();
    		config.objectClass(Item.class).objectField("id").indexed(true);
    		config.add(new UniqueFieldValueConstraint(Item.class, "id"));
    		db.store(new Item(1L));
    		db.store(new Item(1L));
    		db.close();
    	}
    	class Item {
    		public Long id;
    		public Item(Long id) {
    			this.id = id;
    		}
    		@Override
    		public String toString() {
    			return "Item:" + id;
    		}
    	}
    }
    

    The first test correctly throws an UniqueFieldValueConstraintViolationException but the second one don't!

    I've found an other post about this subject (http://developer.db4o.com/forums/th...938.aspx), that states update the db4o configuration after ObjectContainer is opened. The post is dated 2007, maybe now the things are changed...?

    kostia
    Maik Jablonski
    Advanced Member
    Advanced Member
    Posts: 953


    --
    25 May 2009 01:14 PM

    c.cerbo@gmail.com:
    I know that the UniqueFieldValueConstraints should be set in the configuration before opening a new ObjectContainer, but I'd like to know if it's possibile to update the configuration when the ObjectContainer is already open.

    AFAIK this is not possible with current db4o-releases.

    Cheers, Maik

    jease.org >> Java with Ease
    mtz1406
    New Member
    New Member
    Posts: 31


    --
    25 May 2009 01:35 PM

    some configurations must be setting before open the ObjectContainer.One of these configurations is indexing.there is no way to set these for an opened  ObjectContainer. and there is configurations must be setting on the server side.so you must read the API for any configurations you want to set on an opened ObjectContainer or in the client side.

    what about the UniqueFieldValueConstraint?I found nothing about where should use this.but I have no success when try to setting this on opened ObjectContainer.so I think this must be setting on before open the ObjectContainer.

    read this for more information:

    http://developer.db4o.com/Resources...g/Indexing

    http://developer.db4o.com/Resources...onstraints

    but remember there are configurations can be setting on opened ObjectContainer.One of these configurations is cascadeOnUpdate.

     

    mtz1406
    New Member
    New Member
    Posts: 31


    --
    25 May 2009 01:47 PM

    I write the last reply before seeing Cheers, Maik replys.

    c.cerbo@gmail.com
    New Member
    New Member
    Posts: 8


    --
    26 May 2009 02:23 AM

    Okay, thanks a lot for your replies.

    Since is not possibile to add this  constraint when the ObjectContainer is already open, is there a way to check what contraints are set on a class and its fields?

    That may be the workaround for my problem: I check if a class was registered with the UniqueFieldValue, and if not I perform a query before to avoid object duplication.

    kostia
    mtz1406
    New Member
    New Member
    Posts: 31


    --
    26 May 2009 04:55 AM
    c.cerbo@gmail.com:

    is there a way to check what contraints are set on a class and its fields?

    No [at this time]

    May I can help you to work on another solution if you tell me why you need this shortly [give me example] and what is the type of the UniqueFiled? Is it int or String or object? Is it an ID or another thing?

    c.cerbo@gmail.com
    New Member
    New Member
    Posts: 8


    --
    26 May 2009 07:05 AM

    Many thanks for you help offer.

    I use db4o through the JDO (Java Data Object) API and the implementation provided by DataNucleus.

    The problems is in all its details in this Issue on the DataNucleus portal explained:
    http://www.datanucleus.org/servlet/...NUCDBFO-37

    To summarize: DB4O does not enforce uniqueness of identity in the datastore (for application identity) so a check is essential.This check (a normal query) is very bad for performance, therefore I was looking for an alternative solution to ensure the uniqueness.

    Any idea is welcome!

     

    kostia
    mtz1406
    New Member
    New Member
    Posts: 31


    --
    26 May 2009 08:33 AM

     I will give you a good way to Identify your objects

    think you have a User class.create this 2 classes.

    public class UserIDGenerator
    {
        private int ID;
        public UserIDGenerator()
        {
            this.ID = 0;
        }

        public synchronized int getID()
        {
            this.ID++;
            return this.ID;
        }

    }
    public class UserIDManager
    {
        public static synchronized int getID(ObjectContainer db)
        {
            Query query = db.query();
            query.constrain(UserIDGenerator.class);
            ObjectSet result = query.execute();
            UserIDGenerator userIDGenerator = (UserIDGenerator) result.next();
            int ID = userIDGenerator.getID();
            db.store(userIDGenerator);
            db.commit();
            return ID;
        }

    }
    then if you want to create new User just write this:
    User Anonymouse = new User(UserIDManager.getID(db),"Anonymouse");
    db.store(anonymouseGroup);

     this garante that no 2 User objects has the same ID.

    Is this what you want?

    c.cerbo@gmail.com
    New Member
    New Member
    Posts: 8


    --
    26 May 2009 11:01 AM

    No, I need something else.

    Your solution ensures the uniqueness but do not provide the possibility to specify you own ID direct on the object to persist, in a transparent way as the JDO2 Spec requires.

    More Info about JDO2 Application Indentity here: http://www.datanucleus.org/products...ntity.html

    One again, the problem I've encoutered is fully explained at this link: http://www.jpox.org/servlet/jira/br...NUCDBFO-37

    kostia
    jleotta
    Basic Member
    Basic Member
    Posts: 195


    --
    26 May 2009 11:42 AM
    Why can't you use the unique constraint field that already exists in db4o for every object?  This seems to fit the jdo2 spec?
    c.cerbo@gmail.com
    New Member
    New Member
    Posts: 8


    --
    27 May 2009 04:25 AM

    jleotta:
    Why can't you use the unique constraint field that already exists in db4o for every object?  This seems to fit the jdo2 spec?

    My goal is to use the unique constraint field that already exists in db4o, but in the actual JDO2 implementation provide by DataNucleus it's not always possible. Why? the aswer is here: http://www.datanucleus.org/servlet/jira/browse/NUCDBFO-37?focusedCommentId=16668#action_16668 (Andy Jefferson's comment on 25/May/09 07:24 AM, point 2)

    kostia
    You are not authorized to post a reply.


    Active Forums 4.3