Add ShardAware interface and related exit strategy logic

Description

Domain model awareness of its host Shard. Any domain model that implemented a 'ShardAware' interface would contain a Set<ShardId> that could be injected by the relevant ExitStrategy.

This could be solved by adding the following interface:

-------------------------------------------------------
package org.hibernate.shards;

import org.hibernate.shards.ShardId;

import java.util.Set;

/**

  • Interface for persistent objects that are aware of the virtual shardIds

  • that host them.
    */
    public interface ShardAware {


/**

  • Sets the virtual ShardIds that host the implementing
    * persistant object
    *
    * @param shardid
    * a non-null, non-empty Set of ShardIds

  • @throws IllegalArgumentException

  • if <tt>shardIds</tt> is null or empty
    */
    void setShardIds( Set<ShardId> shardids );
    }

---------------------------------------------------

An simple exit strategy that could be used, for example, would set the ShardIds for each resulting ShardAware domain model:

------------------------------------------------------
package org.hibernate.shards.strategy.exit;

import java.util.List;

import org.hibernate.shards.Shard;
import org.hibernate.shards.ShardAware;

/**

  • ShardAwareConcatenateListsExistStrategy sets the ShardIds on each of the given

  • objects returned by each Shard.

  • One should be aware that usage of this class adds O overhead to each retrieval

  • as the setting of each ShardIds Set is invoked by iterating over the entire resultSet.
    */
    public class ShardAwareConcatenateListsExistStrategy extends ConcatenateListsExitStrategy {

@Override
public synchronized boolean addResult(List<Object> oneResult, Shard shard ) {

if ( oneResult != null && ! oneResult.isEmpty()
&& oneResult.get( 0 ) instanceof ShardAware ) {

for( Object object : oneResult ) {
((ShardAware)object).setShardIds( shard.getShardIds() );
}
}

return super.addResult( oneResult, shard );
}
}
---------------------------------------
This change might require changes wherever ShardAccessStrategy.apply() could be invoked.

I have made the changes including a small alteration to the ShardedCriteriaImpl, to use ShardAwareConcatenateListsExistStrategy instead of ConcatenateListsExitStrategy, with success.

Environment

Hibernate 3.2, Database: DB2

Activity

Show:
Max Ross
April 17, 2007, 7:00 AM

Interesting idea Nathan, thanks for writing it up. If your goal is to be able to determine the shard with which an object is associated there's already a facility for it:: ShardedSession.getShardIdForObject(). Is this what you're after or is there something else I'm not seeing?

Also, I noticed you're trying to associate a set of virtual shard ids with a given object. An object will only be associated with 1 virtual shard and 1 physical shard. Looking at the implementation of getShardIdForObject() it looks like it will only return physical shard ids. It seems worthwhile to expose a similar facility for determining virtual shard, but I confess I think I prefer a mechanism that doesn't involve the decoration of model objects. Let me investigate a bit more.

Thanks,
Max

Nathan Silberman
May 1, 2007, 7:15 AM

Thanks for clarifying the virtual/physical shard association. I previously misunderstood that. Allow me to briefly explain my motivation, and perhaps this will help you better assess whether or not you consider this feature to be worthwhile.

I have a project that currently uses Hibernate for the persistance layer that is bound to a single data source. My intention was to be able to add Shards to enable data retrieval from multiple data sources, without having to alter much, if any, code. I imagine this scenario is common.

One of the features we hope to add, was the ability to provide reporting on different data structures per data source. Hence the Shard or Source-aware concept.

The addition of Shards neccessitated (1) the addition of code to configure the Shards from a generic hibernate base class and (2) the actual shard configuration files. These simple steps immedietely enabled me to retrieve objects from multiple databases.

The final step could be done in one of two ways (or perhaps more that I cannot currently imagine): Either add helper methods inside my Hibernate Base class that called ShardedSession.getShardIdForObject() and set this 'source' property on each object or have Shards perform this action.

One could argue that it is an odd coupling. However, it is that much more enticing that the adoption of Shards would not require an addition code change on the adopter's side. The required changes will only be minimized further in the future once it is possible to completely configure Shards from Spring/Guice etc

Assignee

Max Ross

Reporter

Nathan Silberman

Labels

None

Feedback Requested

None

Feedback Requested By

None

backPortable

None

Suitable for new contributors

None

Pull Request

None

backportDecision

None

backportReEvaluate

None

Time tracking

0m

Time remaining

16h

Components

Fix versions

Affects versions

Priority

Major
Configure