Question

I have a system with a db4o server that has two clients. One client is hosted in process, the other is a web server hosting a number of servlets that need to query the database.

In the web server's connection code, I have registered for the commit event, and use it to refresh objects as suggested by the db4o documentation at http://community.versant.com/documentation/reference/db4o-8.0/java/reference/Content/advanced_topics/callbacks/possible_usecases/committed_event_example.htm :

    client = Db4oClientServer.openClient (context.getBean ("db4oClientConfiguration", ClientConfiguration.class),
        arg0.getServletContext ().getInitParameter ("databasehost"),
        Integer.parseInt (arg0.getServletContext ().getInitParameter ("databaseport")),
        arg0.getServletContext ().getInitParameter ("databaseuser"),
        arg0.getServletContext ().getInitParameter ("databasepassword"));

    System.out.println ("DB4O connection established");

    EventRegistry events = EventRegistryFactory.forObjectContainer (client);
    events.committed ().addListener (new EventListener4<CommitEventArgs> () {
        public void onEvent (Event4<CommitEventArgs> commitEvent, CommitEventArgs commitEventArgs)
        {
            for (Iterator4<?> it = commitEventArgs.updated ().iterator (); it.moveNext ();)
            {
                LazyObjectReference reference = (LazyObjectReference) it.current ();
                System.out.println ("Updated object: " + reference.getClass () + ":" + reference.getInternalID ());
                //if (trackedClasses.contains (reference.getClass ()))
                {
                    Object obj = reference.getObject ();
                    commitEventArgs.objectContainer ().ext ().refresh (obj, 1);
                    System.out.println ("  => updated (" + obj + ")");
                }
            }
        }
    });

In the in-process client, the following code is then executed:

    try {
        PlayerCharacter pc = new PlayerCharacter (player, name);
        pc.setBio(bio);
        pc.setArchetype(archetype);
        player.getCharacters ().add (pc);
        database.store (pc);
        database.store (player.getCharacters ());
        database.store (player);
        database.commit ();
        con.sendEvent (id, "CHARACTER_CREATED".getBytes (Constants.CHARSET));
    }
    catch (Exception e) 
    {
        con.sendEvent (id, EventNames.ERROR, e.toString ());
    }

The 'CHARACTER_CREATED' event gets sent successfully, so I know that commit isn't throwing an exception, but nothing shows up on the other client. It continues to use the old versions of the objects, and the 'updated object' messages I'm expecting don't show up on the server console.

Any ideas what I'm doing wrong?

Was it helpful?

Solution

Apparently the .committed() event only fires on a client, when the commit is from a other TCP client.

So you would need to turn your internal .openClient() / .openSession() clients to full blown TCP clients to see the events.

The .openClient() / .openSession() object containers are way more light weight and bypass all code which is related to network communication. Apparently also the event distribution across the network.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top