killbill-aplcache

Changes

api/src/main/java/com/ning/billing/util/entity/UpdatableEntity.java 20(+0 -20)

util/src/main/java/com/ning/billing/util/entity/UpdatableEntityBase.java 29(+0 -29)

Details

diff --git a/account/src/main/java/com/ning/billing/account/api/DefaultAccountEmail.java b/account/src/main/java/com/ning/billing/account/api/DefaultAccountEmail.java
index 2be4a58..4053a32 100644
--- a/account/src/main/java/com/ning/billing/account/api/DefaultAccountEmail.java
+++ b/account/src/main/java/com/ning/billing/account/api/DefaultAccountEmail.java
@@ -18,9 +18,10 @@ package com.ning.billing.account.api;
 
 import java.util.UUID;
 
-import com.ning.billing.util.entity.UpdatableEntityBase;
+import com.ning.billing.util.entity.Entity;
+import com.ning.billing.util.entity.EntityBase;
 
-public class DefaultAccountEmail extends UpdatableEntityBase implements AccountEmail {
+public class DefaultAccountEmail extends EntityBase implements AccountEmail, Entity {
     private final UUID accountId;
     private final String email;
 
diff --git a/account/src/main/java/com/ning/billing/account/api/svcs/DefaultAccountInternalApi.java b/account/src/main/java/com/ning/billing/account/api/svcs/DefaultAccountInternalApi.java
index b29bc91..8de582c 100644
--- a/account/src/main/java/com/ning/billing/account/api/svcs/DefaultAccountInternalApi.java
+++ b/account/src/main/java/com/ning/billing/account/api/svcs/DefaultAccountInternalApi.java
@@ -57,25 +57,25 @@ public class DefaultAccountInternalApi implements AccountInternalApi {
 
     @Override
     public Account getAccountByRecordId(final Long recordId,
-            final InternalTenantContext context) throws AccountApiException {
+                                        final InternalTenantContext context) throws AccountApiException {
         return accountDao.getByRecordId(recordId, context);
     }
 
     @Override
     public void updateAccount(final String externalKey, final AccountData accountData,
-            final InternalCallContext context) throws AccountApiException {
-        final Account account = getAccountByKey(externalKey, context);
+                              final InternalCallContext context) throws AccountApiException {
         try {
+            final Account account = getAccountByKey(externalKey, context);
             final Account updatedAccount = new DefaultAccount(account.getId(), accountData);
-            accountDao.update(updatedAccount,context);
-        } catch (final EntityPersistenceException e) {
-            throw new AccountApiException(e, ErrorCode.ACCOUNT_UPDATE_FAILED);
+            accountDao.update(updatedAccount, context);
+        } catch (EntityPersistenceException e) {
+            throw new AccountApiException(e, ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID);
         }
     }
 
     @Override
     public List<AccountEmail> getEmails(final UUID accountId,
-            final InternalTenantContext context)  {
+                                        final InternalTenantContext context) {
         return accountEmailDao.getEmails(accountId, context);
     }
 
@@ -97,7 +97,7 @@ public class DefaultAccountInternalApi implements AccountInternalApi {
 
     @Override
     public void updatePaymentMethod(final UUID accountId, final UUID paymentMethodId,
-            final InternalCallContext context) throws AccountApiException {
+                                    final InternalCallContext context) throws AccountApiException {
         try {
             accountDao.updatePaymentMethod(accountId, paymentMethodId, context);
         } catch (final EntityPersistenceException e) {
diff --git a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
index bd2c79c..b1e3353 100644
--- a/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
+++ b/account/src/main/java/com/ning/billing/account/api/user/DefaultAccountUserApi.java
@@ -19,8 +19,6 @@ package com.ning.billing.account.api.user;
 import java.util.List;
 import java.util.UUID;
 
-import javax.annotation.Nullable;
-
 import org.joda.time.DateTime;
 
 import com.ning.billing.ErrorCode;
@@ -104,19 +102,21 @@ public class DefaultAccountUserApi implements AccountUserApi {
         try {
             accountDao.update(account, internalCallContextFactory.createInternalCallContext(account.getId(), context));
         } catch (EntityPersistenceException e) {
-            throw new AccountApiException(e, ErrorCode.ACCOUNT_UPDATE_FAILED);
+            throw new AccountApiException(e, ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID, account.getId());
         }
+
     }
 
     @Override
     public void updateAccount(final UUID accountId, final AccountData accountData, final CallContext context)
             throws AccountApiException {
-        final Account account = new DefaultAccount(accountId, accountData);
-
         try {
+            final Account account = new DefaultAccount(accountId, accountData);
             accountDao.update(account, internalCallContextFactory.createInternalCallContext(account.getId(), context));
         } catch (EntityPersistenceException e) {
-            throw new AccountApiException(e, e.getCode(), e.getMessage());
+            throw new AccountApiException(e, ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID);
+        } catch (RuntimeException e /* EntityPersistenceException */) {
+            throw new AccountApiException(e, ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID, accountId);
         }
     }
 
diff --git a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
index c7dd36f..ee9edb0 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AccountDao.java
@@ -23,9 +23,10 @@ import com.ning.billing.account.api.AccountApiException;
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.callcontext.InternalTenantContext;
 import com.ning.billing.util.entity.EntityPersistenceException;
+import com.ning.billing.util.entity.dao.EntityDao;
 import com.ning.billing.util.entity.dao.UpdatableEntityDao;
 
-public interface AccountDao extends UpdatableEntityDao<Account> {
+public interface AccountDao extends EntityDao<Account> {
 
     public Account getAccountByKey(String key, InternalTenantContext context);
 
@@ -39,4 +40,6 @@ public interface AccountDao extends UpdatableEntityDao<Account> {
      * @param paymentMethodId the is of the current default paymentMethod
      */
     public void updatePaymentMethod(UUID accountId, UUID paymentMethodId, InternalCallContext context) throws EntityPersistenceException;
+
+    public void update(Account account, InternalCallContext context) throws EntityPersistenceException;
 }
diff --git a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java
index c8605bf..5cbf61e 100644
--- a/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java
+++ b/account/src/main/java/com/ning/billing/account/dao/AuditedAccountDao.java
@@ -139,47 +139,39 @@ public class AuditedAccountDao implements AccountDao {
     }
 
     @Override
-    public void update(final Account specifiedAccount, final InternalCallContext context) throws EntityPersistenceException {
-        try {
-            transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
-                @Override
-                public Void inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws EntityPersistenceException, InternalBus.EventBusException {
-                    final AccountSqlDao transactional = entitySqlDaoWrapperFactory.become(AccountSqlDao.class);
-
-                    final UUID accountId = specifiedAccount.getId();
-                    final Account currentAccount = transactional.getById(accountId.toString(), context);
-                    if (currentAccount == null) {
-                        throw new EntityPersistenceException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID, accountId);
-                    }
-
-                    // Set unspecified (null) fields to their current values
-                    final Account account = specifiedAccount.mergeWithDelegate(currentAccount);
-
-                    transactional.update(account, context);
+    public void update(final Account specifiedAccount, final InternalCallContext context) {
+        transactionalSqlDao.execute(new EntitySqlDaoTransactionWrapper<Void>() {
+            @Override
+            public Void inTransaction(final EntitySqlDaoWrapperFactory<EntitySqlDao> entitySqlDaoWrapperFactory) throws EntityPersistenceException, InternalBus.EventBusException {
+                final AccountSqlDao transactional = entitySqlDaoWrapperFactory.become(AccountSqlDao.class);
+
+                final UUID accountId = specifiedAccount.getId();
+                final Account currentAccount = transactional.getById(accountId.toString(), context);
+                if (currentAccount == null) {
+                    throw new EntityPersistenceException(ErrorCode.ACCOUNT_DOES_NOT_EXIST_FOR_ID, accountId);
+                }
 
-                    final AccountChangeInternalEvent changeEvent = new DefaultAccountChangeEvent(accountId,
-                            context.getUserToken(),
-                            currentAccount,
-                            account,
-                            context.getAccountRecordId(),
-                            context.getTenantRecordId());
-                    if (changeEvent.hasChanges()) {
-                        try {
-                            eventBus.postFromTransaction(changeEvent, transactional, context);
-                        } catch (final EventBusException e) {
-                            log.warn("Failed to post account change event for account " + accountId, e);
-                        }
+                // Set unspecified (null) fields to their current values
+                final Account account = specifiedAccount.mergeWithDelegate(currentAccount);
+                transactional.update(account, context);
+
+                final AccountChangeInternalEvent changeEvent = new DefaultAccountChangeEvent(accountId,
+                                                                                             context.getUserToken(),
+                                                                                             currentAccount,
+                                                                                             account,
+                                                                                             context.getAccountRecordId(),
+                                                                                             context.getTenantRecordId());
+                if (changeEvent.hasChanges()) {
+                    try {
+                        eventBus.postFromTransaction(changeEvent, transactional, context);
+                    } catch (final EventBusException e) {
+                        log.warn("Failed to post account change event for account " + accountId, e);
                     }
-                    return null;
                 }
-            });
-        } catch (final RuntimeException re) {
-            if (re.getCause() instanceof EntityPersistenceException) {
-                throw (EntityPersistenceException) re.getCause();
-            } else {
-                throw re;
+
+                return null;
             }
-        }
+        });
     }
 
     @Override
@@ -204,7 +196,7 @@ public class AuditedAccountDao implements AccountDao {
 
                     final Account account = transactional.getById(accountId.toString(), context);
                     final AccountChangeInternalEvent changeEvent = new DefaultAccountChangeEvent(accountId, context.getUserToken(), currentAccount, account,
-                            context.getAccountRecordId(), context.getTenantRecordId());
+                                                                                                 context.getAccountRecordId(), context.getTenantRecordId());
 
                     if (changeEvent.hasChanges()) {
                         try {
diff --git a/api/src/main/java/com/ning/billing/account/api/Account.java b/api/src/main/java/com/ning/billing/account/api/Account.java
index 7a9b8f9..0fdbbd2 100644
--- a/api/src/main/java/com/ning/billing/account/api/Account.java
+++ b/api/src/main/java/com/ning/billing/account/api/Account.java
@@ -17,7 +17,7 @@
 package com.ning.billing.account.api;
 
 import com.ning.billing.junction.api.Blockable;
-import com.ning.billing.util.entity.UpdatableEntity;
+import com.ning.billing.util.entity.Entity;
 
 /**
  * The interface <code>Account</code> represents an account within Killbill.
@@ -29,7 +29,7 @@ import com.ning.billing.util.entity.UpdatableEntity;
  * @see com.ning.billing.account.api.AccountData
  */
 
-public interface Account extends AccountData, UpdatableEntity, Blockable {
+public interface Account extends AccountData, Entity, Blockable {
 
     /**
      *
diff --git a/api/src/main/java/com/ning/billing/account/api/AccountEmail.java b/api/src/main/java/com/ning/billing/account/api/AccountEmail.java
index 5ac42af..10145ef 100644
--- a/api/src/main/java/com/ning/billing/account/api/AccountEmail.java
+++ b/api/src/main/java/com/ning/billing/account/api/AccountEmail.java
@@ -18,9 +18,9 @@ package com.ning.billing.account.api;
 
 import java.util.UUID;
 
-import com.ning.billing.util.entity.UpdatableEntity;
+import com.ning.billing.util.entity.Entity;
 
-public interface AccountEmail extends UpdatableEntity {
+public interface AccountEmail extends Entity {
 
     /**
      *
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/timeline/BundleTimeline.java b/api/src/main/java/com/ning/billing/entitlement/api/timeline/BundleTimeline.java
index cfc3bab..ed85d3f 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/timeline/BundleTimeline.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/timeline/BundleTimeline.java
@@ -19,12 +19,14 @@ package com.ning.billing.entitlement.api.timeline;
 import java.util.List;
 import java.util.UUID;
 
+import com.ning.billing.util.entity.Entity;
+
 /**
  *  The interface {@code BundleTimeline} shows a view of all the entitlement events for a specific
  *  {@code SubscriptionBundle}.
  *
  */
-public interface BundleTimeline {
+public interface BundleTimeline extends Entity {
 
     /**
      *
@@ -36,7 +38,7 @@ public interface BundleTimeline {
      *
      * @return the unique id for the {@SubscriptionBundle}
      */
-    UUID getBundleId();
+    UUID getId();
 
     /**
      *
diff --git a/api/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionTimeline.java b/api/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionTimeline.java
index a521e89..aaa1b40 100644
--- a/api/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionTimeline.java
+++ b/api/src/main/java/com/ning/billing/entitlement/api/timeline/SubscriptionTimeline.java
@@ -22,6 +22,7 @@ import org.joda.time.DateTime;
 
 import com.ning.billing.catalog.api.PlanPhaseSpecifier;
 import com.ning.billing.entitlement.api.SubscriptionTransitionType;
+import com.ning.billing.util.entity.Entity;
 
 /**
  * The interface {@code} shows a view of all the events for a particular {@code Subscription}.
@@ -29,13 +30,7 @@ import com.ning.billing.entitlement.api.SubscriptionTransitionType;
  * It can be used to display information, or it can be used to modify the entitlement stream of events
  * and 'repair' the stream by versioning the events.
  */
-public interface SubscriptionTimeline {
-
-    /**
-     *
-     * @return the unique id for that {@code Subscription}
-     */
-    public UUID getId();
+public interface SubscriptionTimeline extends Entity {
 
     /**
      *
diff --git a/api/src/main/java/com/ning/billing/junction/api/Blockable.java b/api/src/main/java/com/ning/billing/junction/api/Blockable.java
index 20ac9ca..8e3f5cf 100644
--- a/api/src/main/java/com/ning/billing/junction/api/Blockable.java
+++ b/api/src/main/java/com/ning/billing/junction/api/Blockable.java
@@ -22,8 +22,9 @@ import com.ning.billing.ObjectType;
 import com.ning.billing.account.api.Account;
 import com.ning.billing.entitlement.api.user.Subscription;
 import com.ning.billing.entitlement.api.user.SubscriptionBundle;
+import com.ning.billing.util.entity.Entity;
 
-public interface Blockable {
+public interface Blockable extends Entity {
 
     public enum Type {
         ACCOUNT,
@@ -71,6 +72,7 @@ public interface Blockable {
         }
     }
 
+    @Override
     public UUID getId();
 
     public BlockingState getBlockingState();
diff --git a/api/src/main/java/com/ning/billing/junction/api/BlockingState.java b/api/src/main/java/com/ning/billing/junction/api/BlockingState.java
index 81416c5..a324506 100644
--- a/api/src/main/java/com/ning/billing/junction/api/BlockingState.java
+++ b/api/src/main/java/com/ning/billing/junction/api/BlockingState.java
@@ -18,8 +18,10 @@ package com.ning.billing.junction.api;
 
 import org.joda.time.DateTime;
 
+import com.ning.billing.util.entity.Entity;
 
-public interface BlockingState extends Comparable<BlockingState> {
+
+public interface BlockingState extends Entity, Comparable<BlockingState> {
 
     public abstract String getStateName();
 
diff --git a/api/src/main/java/com/ning/billing/tenant/api/TenantKV.java b/api/src/main/java/com/ning/billing/tenant/api/TenantKV.java
index 0103440..cf34a62 100644
--- a/api/src/main/java/com/ning/billing/tenant/api/TenantKV.java
+++ b/api/src/main/java/com/ning/billing/tenant/api/TenantKV.java
@@ -16,7 +16,9 @@
 package com.ning.billing.tenant.api;
 
 
-public interface TenantKV {
+import com.ning.billing.util.entity.Entity;
+
+public interface TenantKV extends Entity {
 
     public String getKey();
 
diff --git a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
index a68afe6..d3fd015 100644
--- a/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
+++ b/beatrix/src/test/java/com/ning/billing/beatrix/integration/TestRepairIntegration.java
@@ -181,6 +181,16 @@ public class TestRepairIntegration extends TestIntegrationBase {
             }
 
             @Override
+            public DateTime getCreatedDate() {
+                return null;
+            }
+
+            @Override
+            public DateTime getUpdatedDate() {
+                return null;
+            }
+
+            @Override
             public List<NewEvent> getNewEvents() {
                 return newEvents;
             }
@@ -216,11 +226,21 @@ public class TestRepairIntegration extends TestIntegrationBase {
             }
 
             @Override
-            public UUID getBundleId() {
+            public UUID getId() {
                 return bundleId;
             }
 
             @Override
+            public DateTime getCreatedDate() {
+                return null;
+            }
+
+            @Override
+            public DateTime getUpdatedDate() {
+                return null;
+            }
+
+            @Override
             public String getExternalKey() {
                 return null;
             }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
index 67d9e3d..4e0d044 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultEntitlementTimelineApi.java
@@ -117,20 +117,20 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
     public BundleTimeline repairBundle(final BundleTimeline input, final boolean dryRun, final CallContext context) throws EntitlementRepairException {
         final InternalTenantContext tenantContext = internalCallContextFactory.createInternalTenantContext(context);
         try {
-            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(input.getBundleId(), tenantContext);
+            final SubscriptionBundle bundle = dao.getSubscriptionBundleFromId(input.getId(), tenantContext);
             if (bundle == null) {
-                throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_BUNDLE, input.getBundleId());
+                throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_UNKNOWN_BUNDLE, input.getId());
             }
 
             // Subscriptions are ordered with BASE subscription first-- if exists
-            final List<Subscription> subscriptions = dao.getSubscriptions(factory, input.getBundleId(), tenantContext);
+            final List<Subscription> subscriptions = dao.getSubscriptions(factory, input.getId(), tenantContext);
             if (subscriptions.size() == 0) {
-                throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NO_ACTIVE_SUBSCRIPTIONS, input.getBundleId());
+                throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_NO_ACTIVE_SUBSCRIPTIONS, input.getId());
             }
 
             final String viewId = getViewId(((SubscriptionBundleData) bundle).getLastSysUpdateTime(), subscriptions);
             if (!viewId.equals(input.getViewId())) {
-                throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_VIEW_CHANGED, input.getBundleId(), input.getViewId(), viewId);
+                throw new EntitlementRepairException(ErrorCode.ENT_REPAIR_VIEW_CHANGED, input.getId(), input.getViewId(), viewId);
             }
 
             DateTime firstDeletedBPEventTime = null;
@@ -232,10 +232,10 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
                 baseSubscriptionRepair.addFutureAddonCancellation(addOnSubscriptionInRepair, context);
 
                 final List<SubscriptionTimeline> repairs = createGetSubscriptionRepairList(subscriptions, convertDataRepair(inRepair));
-                return createGetBundleRepair(input.getBundleId(), bundle.getKey(), input.getViewId(), repairs);
+                return createGetBundleRepair(input.getId(), bundle.getKey(), input.getViewId(), repairs);
             } else {
-                dao.repair(bundle.getAccountId(), input.getBundleId(), inRepair, internalCallContextFactory.createInternalCallContext(bundle.getAccountId(), context));
-                return getBundleTimeline(input.getBundleId(), context);
+                dao.repair(bundle.getAccountId(), input.getId(), inRepair, internalCallContextFactory.createInternalCallContext(bundle.getAccountId(), context));
+                return getBundleTimeline(input.getId(), context);
             }
         } catch (CatalogApiException e) {
             throw new EntitlementRepairException(e);
@@ -391,11 +391,21 @@ public class DefaultEntitlementTimelineApi implements EntitlementTimelineApi {
             }
 
             @Override
-            public UUID getBundleId() {
+            public UUID getId() {
                 return bundleId;
             }
 
             @Override
+            public DateTime getCreatedDate() {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public DateTime getUpdatedDate() {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
             public String getExternalKey() {
                 return externalKey;
             }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultSubscriptionTimeline.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultSubscriptionTimeline.java
index d8331e7..343dfed 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultSubscriptionTimeline.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/timeline/DefaultSubscriptionTimeline.java
@@ -13,6 +13,7 @@
  * License for the specific language governing permissions and limitations
  * under the License.
  */
+
 package com.ning.billing.entitlement.api.timeline;
 
 import java.util.ArrayList;
@@ -38,6 +39,7 @@ import com.ning.billing.entitlement.events.phase.PhaseEvent;
 import com.ning.billing.entitlement.events.user.ApiEvent;
 import com.ning.billing.entitlement.events.user.ApiEventType;
 
+
 public class DefaultSubscriptionTimeline implements SubscriptionTimeline {
 
     private final UUID id;
@@ -58,12 +60,12 @@ public class DefaultSubscriptionTimeline implements SubscriptionTimeline {
         this.id = input.getId();
         this.activeVersion = input.getActiveVersion();
         this.existingEvents = (input.getExistingEvents() != null) ? new ArrayList<SubscriptionTimeline.ExistingEvent>(input.getExistingEvents()) :
-                Collections.<SubscriptionTimeline.ExistingEvent>emptyList();
+                              Collections.<SubscriptionTimeline.ExistingEvent>emptyList();
         sortExistingEvent(this.existingEvents);
         this.deletedEvents = (input.getDeletedEvents() != null) ? new ArrayList<SubscriptionTimeline.DeletedEvent>(input.getDeletedEvents()) :
-                Collections.<SubscriptionTimeline.DeletedEvent>emptyList();
+                             Collections.<SubscriptionTimeline.DeletedEvent>emptyList();
         this.newEvents = (input.getNewEvents() != null) ? new ArrayList<SubscriptionTimeline.NewEvent>(input.getNewEvents()) :
-                Collections.<SubscriptionTimeline.NewEvent>emptyList();
+                         Collections.<SubscriptionTimeline.NewEvent>emptyList();
         sortNewEvent(this.newEvents);
     }
 
@@ -264,6 +266,16 @@ public class DefaultSubscriptionTimeline implements SubscriptionTimeline {
     }
 
     @Override
+    public DateTime getCreatedDate() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public DateTime getUpdatedDate() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
     public List<DeletedEvent> getDeletedEvents() {
         return deletedEvents;
     }
diff --git a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
index 87516f4..8e0630a 100644
--- a/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
+++ b/entitlement/src/main/java/com/ning/billing/entitlement/api/user/SubscriptionBundleData.java
@@ -24,14 +24,12 @@ import org.joda.time.DateTime;
 
 import com.ning.billing.junction.api.BlockingState;
 import com.ning.billing.overdue.OverdueState;
+import com.ning.billing.util.entity.EntityBase;
 
-public class SubscriptionBundleData implements SubscriptionBundle {
+public class SubscriptionBundleData extends EntityBase implements SubscriptionBundle {
 
-    private final UUID id;
     private final String key;
     private final UUID accountId;
-    private final DateTime createdDate;
-    private final DateTime updatedDate;
     private final DateTime lastSysTimeUpdate;
     private final OverdueState<SubscriptionBundle> overdueState;
 
@@ -44,15 +42,12 @@ public class SubscriptionBundleData implements SubscriptionBundle {
     }
 
     public SubscriptionBundleData(final UUID id, final String key, final UUID accountId, final DateTime lastSysUpdate, @Nullable final OverdueState<SubscriptionBundle> overdueState) {
-        this.id = id;
+        // TODO add column in bundles table
+        super(id, null, null);
         this.key = key;
         this.accountId = accountId;
         this.lastSysTimeUpdate = lastSysUpdate;
         this.overdueState = overdueState;
-
-        // TODO add column in bundles table
-        createdDate = null;
-        updatedDate = null;
     }
 
     @Override
@@ -61,21 +56,6 @@ public class SubscriptionBundleData implements SubscriptionBundle {
     }
 
     @Override
-    public UUID getId() {
-        return id;
-    }
-
-    @Override
-    public DateTime getCreatedDate() {
-        return createdDate;
-    }
-
-    @Override
-    public DateTime getUpdatedDate() {
-        return updatedDate;
-    }
-
-    @Override
     public UUID getAccountId() {
         return accountId;
     }
diff --git a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestApiBaseRepair.java b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestApiBaseRepair.java
index 6fb3525..bec35c0 100644
--- a/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestApiBaseRepair.java
+++ b/entitlement/src/test/java/com/ning/billing/entitlement/api/timeline/TestApiBaseRepair.java
@@ -41,13 +41,16 @@ import com.ning.billing.entitlement.api.user.EntitlementUserApiException;
 import static org.testng.Assert.assertEquals;
 
 public abstract class TestApiBaseRepair extends TestApiBase {
+
     protected static final Logger log = LoggerFactory.getLogger(TestApiBaseRepair.class);
 
     public interface TestWithExceptionCallback {
+
         public void doTest() throws EntitlementRepairException, EntitlementUserApiException;
     }
 
     public static class TestWithException {
+
         public void withException(final TestWithExceptionCallback callback, final ErrorCode code) throws Exception {
             try {
                 callback.doTest();
@@ -66,6 +69,16 @@ public abstract class TestApiBaseRepair extends TestApiBase {
             }
 
             @Override
+            public DateTime getCreatedDate() {
+                return null;
+            }
+
+            @Override
+            public DateTime getUpdatedDate() {
+                return null;
+            }
+
+            @Override
             public List<NewEvent> getNewEvents() {
                 return newEvents;
             }
@@ -100,11 +113,21 @@ public abstract class TestApiBaseRepair extends TestApiBase {
             }
 
             @Override
-            public UUID getBundleId() {
+            public UUID getId() {
                 return bundleId;
             }
 
             @Override
+            public DateTime getCreatedDate() {
+                return null;
+            }
+
+            @Override
+            public DateTime getUpdatedDate() {
+                return null;
+            }
+
+            @Override
             public String getExternalKey() {
                 return null;
             }
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
index 0a177e8..cb191c4 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/AccountTimelineJson.java
@@ -82,7 +82,7 @@ public class AccountTimelineJson {
         final StringBuilder tmp = new StringBuilder();
         for (final UUID cur : b) {
             for (final BundleTimeline bt : bundles) {
-                if (bt.getBundleId().equals(cur)) {
+                if (bt.getId().equals(cur)) {
                     if (!first) {
                         tmp.append(",");
                     }
@@ -120,7 +120,7 @@ public class AccountTimelineJson {
         this.account = new AccountJsonSimple(account.getId().toString(), account.getExternalKey());
         this.bundles = new LinkedList<BundleJsonWithSubscriptions>();
         for (final BundleTimeline bundle : bundles) {
-            final List<AuditLog> bundleAuditLogs = bundlesAuditLogs.get(bundle.getBundleId());
+            final List<AuditLog> bundleAuditLogs = bundlesAuditLogs.get(bundle.getId());
             final BundleJsonWithSubscriptions jsonWithSubscriptions = new BundleJsonWithSubscriptions(bundle, bundleAuditLogs,
                                                                                                       subscriptionsAuditLogs, subscriptionEventsAuditLogs);
             this.bundles.add(jsonWithSubscriptions);
diff --git a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonWithSubscriptions.java b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonWithSubscriptions.java
index 8fd820e..af8900a 100644
--- a/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonWithSubscriptions.java
+++ b/jaxrs/src/main/java/com/ning/billing/jaxrs/json/BundleJsonWithSubscriptions.java
@@ -50,10 +50,10 @@ public class BundleJsonWithSubscriptions extends BundleJsonSimple {
 
     public BundleJsonWithSubscriptions(final BundleTimeline bundle, final List<AuditLog> auditLogs,
                                        final Map<UUID, List<AuditLog>> subscriptionsAuditLogs, final Map<UUID, List<AuditLog>> subscriptionEventsAuditLogs) {
-        super(bundle.getBundleId(), bundle.getExternalKey(), auditLogs);
+        super(bundle.getId(), bundle.getExternalKey(), auditLogs);
         this.subscriptions = new LinkedList<SubscriptionJsonWithEvents>();
         for (final SubscriptionTimeline subscriptionTimeline : bundle.getSubscriptions()) {
-            this.subscriptions.add(new SubscriptionJsonWithEvents(bundle.getBundleId(), subscriptionTimeline,
+            this.subscriptions.add(new SubscriptionJsonWithEvents(bundle.getId(), subscriptionTimeline,
                                                                   subscriptionsAuditLogs.get(subscriptionTimeline.getId()), subscriptionEventsAuditLogs));
         }
     }
diff --git a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
index 8f3ac82..a5551cf 100644
--- a/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
+++ b/jaxrs/src/test/java/com/ning/billing/jaxrs/json/TestBundleJsonWithSubscriptions.java
@@ -93,7 +93,7 @@ public class TestBundleJsonWithSubscriptions extends JaxrsTestSuite {
         final BundleTimeline bundleTimeline = Mockito.mock(BundleTimeline.class);
         final UUID bundleId = UUID.randomUUID();
         final String externalKey = UUID.randomUUID().toString();
-        Mockito.when(bundleTimeline.getBundleId()).thenReturn(bundleId);
+        Mockito.when(bundleTimeline.getId()).thenReturn(bundleId);
         Mockito.when(bundleTimeline.getExternalKey()).thenReturn(externalKey);
         Mockito.when(bundleTimeline.getSubscriptions()).thenReturn(ImmutableList.<SubscriptionTimeline>of(subscriptionTimeline));
 
@@ -118,7 +118,7 @@ public class TestBundleJsonWithSubscriptions extends JaxrsTestSuite {
         final BundleTimeline bundle = Mockito.mock(BundleTimeline.class);
         final UUID bundleId = UUID.randomUUID();
         final String externalKey = UUID.randomUUID().toString();
-        Mockito.when(bundle.getBundleId()).thenReturn(bundleId);
+        Mockito.when(bundle.getId()).thenReturn(bundleId);
         Mockito.when(bundle.getExternalKey()).thenReturn(externalKey);
 
         final BundleJsonWithSubscriptions bundleJsonWithSubscriptions = new BundleJsonWithSubscriptions(bundle, null,
diff --git a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java
index 776e144..c9260dc 100644
--- a/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java
+++ b/junction/src/main/java/com/ning/billing/junction/dao/BlockingStateSqlDao.java
@@ -86,6 +86,7 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
         public BlockingState map(final int index, final ResultSet r, final StatementContext ctx)
                 throws SQLException {
 
+            final UUID id;
             final DateTime timestamp;
             final UUID blockableId;
             final String stateName;
@@ -94,19 +95,24 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
             final boolean blockEntitlement;
             final boolean blockBilling;
             final Type type;
+            DateTime createdDate;
+            DateTime updatedDate;
+
             try {
+                id = UUID.fromString(r.getString("id"));
                 timestamp = getDateTime(r, "created_date");
-                blockableId = UUID.fromString(r.getString("id"));
+                blockableId = UUID.fromString(r.getString("blockable_id"));
                 stateName = r.getString("state") == null ? DefaultBlockingState.CLEAR_STATE_NAME : r.getString("state");
                 type = Type.get(r.getString("type"));
                 service = r.getString("service");
                 blockChange = r.getBoolean("block_change");
                 blockEntitlement = r.getBoolean("block_entitlement");
                 blockBilling = r.getBoolean("block_billing");
+                createdDate = getDateTime(r, "created_date");
             } catch (BlockingApiException e) {
                 throw new SQLException(e);
             }
-            return new DefaultBlockingState(blockableId, stateName, type, service, blockChange, blockEntitlement, blockBilling, timestamp);
+            return new DefaultBlockingState(id, blockableId, stateName, type, service, blockChange, blockEntitlement, blockBilling, timestamp, createdDate);
         }
     }
 
@@ -123,7 +129,8 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
 
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final DefaultBlockingState state) {
-            stmt.bind("id", state.getBlockedId().toString());
+            stmt.bind("id", state.getId().toString());
+            stmt.bind("blockable_id", state.getBlockedId().toString());
             stmt.bind("state", state.getStateName().toString());
             stmt.bind("type", state.getType().toString());
             stmt.bind("service", state.getService().toString());
@@ -137,7 +144,7 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
 
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final UUID id) {
-            stmt.bind("id", id.toString());
+            stmt.bind("blockable_id", id.toString());
         }
     }
 
@@ -145,7 +152,7 @@ public interface BlockingStateSqlDao extends BlockingStateDao, CloseMe, Transmog
 
         @Override
         public void bind(@SuppressWarnings("rawtypes") final SQLStatement stmt, final Bind bind, final Blockable overdueable) {
-            stmt.bind("id", overdueable.getId().toString());
+            stmt.bind("blockable_id", overdueable.getId().toString());
         }
     }
 
diff --git a/junction/src/main/resources/com/ning/billing/junction/dao/BlockingStateSqlDao.sql.stg b/junction/src/main/resources/com/ning/billing/junction/dao/BlockingStateSqlDao.sql.stg
index 608db22..9a9077d 100644
--- a/junction/src/main/resources/com/ning/billing/junction/dao/BlockingStateSqlDao.sql.stg
+++ b/junction/src/main/resources/com/ning/billing/junction/dao/BlockingStateSqlDao.sql.stg
@@ -6,6 +6,7 @@ AND_CHECK_TENANT() ::= "AND <CHECK_TENANT()>"
 getBlockingStateFor() ::= <<
     select
         id
+      , blockable_id
       , state
       , type
       , service
@@ -15,7 +16,7 @@ getBlockingStateFor() ::= <<
       , created_date
       , tenant_record_id
     from blocking_states
-    where id = :id
+    where blockable_id = :blockable_id
     <AND_CHECK_TENANT()>
     -- We want the current state, hence the order desc and limit 1
     order by created_date desc, record_id desc
@@ -26,6 +27,7 @@ getBlockingStateFor() ::= <<
 getBlockingHistoryFor() ::= <<
     select
        id
+      , blockable_id
       , state
       , type
       , service
@@ -35,7 +37,7 @@ getBlockingHistoryFor() ::= <<
       , created_date
       , tenant_record_id
     from blocking_states
-    where id = :id
+    where blockable_id = :blockable_id
     <AND_CHECK_TENANT()>
     -- We want the history in order
     order by created_date asc, record_id asc
@@ -45,6 +47,7 @@ getBlockingHistoryFor() ::= <<
 setBlockingState() ::= <<
     insert into blocking_states (
        id
+      , blockable_id
       , state
       , type
       , service
@@ -56,6 +59,7 @@ setBlockingState() ::= <<
       , tenant_record_id
     ) values (
         :id
+      , :blockable_id
       , :state
       , :type
       , :service
diff --git a/junction/src/main/resources/com/ning/billing/junction/ddl.sql b/junction/src/main/resources/com/ning/billing/junction/ddl.sql
index 90b8158..cf3ddb0 100644
--- a/junction/src/main/resources/com/ning/billing/junction/ddl.sql
+++ b/junction/src/main/resources/com/ning/billing/junction/ddl.sql
@@ -2,6 +2,7 @@ DROP TABLE IF EXISTS blocking_states;
 CREATE TABLE blocking_states (
     record_id int(11) unsigned NOT NULL AUTO_INCREMENT,
     id char(36) NOT NULL,
+    blockable_id char(36) NOT NULL,
     type varchar(20) NOT NULL,
     state varchar(50) NOT NULL,
     service varchar(20) NOT NULL,
@@ -13,5 +14,5 @@ CREATE TABLE blocking_states (
     tenant_record_id int(11) unsigned default null,
     PRIMARY KEY(record_id)
 ) ENGINE=innodb;
-CREATE INDEX blocking_states_id ON blocking_states(id);
+CREATE INDEX blocking_states_id ON blocking_states(blockable_id);
 CREATE INDEX blocking_states_tenant_account_record_id ON blocking_states(tenant_record_id, account_record_id);
diff --git a/junction/src/test/java/com/ning/billing/junction/api/blocking/TestDefaultBlockingApi.java b/junction/src/test/java/com/ning/billing/junction/api/blocking/TestDefaultBlockingApi.java
index 149ebb5..5d1c7a2 100644
--- a/junction/src/test/java/com/ning/billing/junction/api/blocking/TestDefaultBlockingApi.java
+++ b/junction/src/test/java/com/ning/billing/junction/api/blocking/TestDefaultBlockingApi.java
@@ -72,7 +72,7 @@ public class TestDefaultBlockingApi extends JunctionTestSuiteWithEmbeddedDB {
             }
         });
 
-        final BlockingState blockingState = new DefaultBlockingState(bundleId, "BLOCKED", Type.SUBSCRIPTION_BUNDLE, "myService", true, true, true, internalCallContext.getCreatedDate());
+        final BlockingState blockingState = new DefaultBlockingState(UUID.randomUUID(), bundleId, "BLOCKED", Type.SUBSCRIPTION_BUNDLE, "myService", true, true, true, internalCallContext.getCreatedDate(), null);
         blockingApi.setBlockingState(blockingState, internalCallContext);
 
         // Verify the blocking state was applied
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java
index e268b3a..3b628c6 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBillingApi.java
@@ -225,8 +225,8 @@ public class TestBillingApi extends JunctionTestSuite {
         final Account account = createAccount(32);
 
         final List<BlockingState> blockingStates = new ArrayList<BlockingState>();
-        blockingStates.add(new DefaultBlockingState(bunId, DISABLED_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
-        blockingStates.add(new DefaultBlockingState(bunId, CLEAR_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
+        blockingStates.add(new DefaultBlockingState(UUID.randomUUID(), bunId, DISABLED_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1), null));
+        blockingStates.add(new DefaultBlockingState(UUID.randomUUID(),bunId, CLEAR_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2), null));
 
         final BlockingCalculator blockingCal = new BlockingCalculator(new BlockingInternalApi() {
             @Override
diff --git a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java
index d69a9e1..89ca328 100644
--- a/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java
+++ b/junction/src/test/java/com/ning/billing/junction/plumbing/billing/TestBlockingCalculator.java
@@ -136,8 +136,8 @@ public class TestBlockingCalculator extends JunctionTestSuite {
         billingEvents.add(D);
 
         final List<BlockingState> blockingStates = new ArrayList<BlockingState>();
-        blockingStates.add(new DefaultBlockingState(bundleId1, DISABLED_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now));
-        blockingStates.add(new DefaultBlockingState(bundleId1, CLEAR_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
+        blockingStates.add(new DefaultBlockingState(UUID.randomUUID(), bundleId1, DISABLED_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now, null));
+        blockingStates.add(new DefaultBlockingState(UUID.randomUUID(), bundleId1, CLEAR_BUNDLE, Blockable.Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2), null));
 
         Mockito.when(blockingApi.getBlockingHistory(bundleId1, internalCallContext)).thenReturn(blockingStates);
 
@@ -669,8 +669,8 @@ public class TestBlockingCalculator extends JunctionTestSuite {
 
         //simple events open clear -> disabled
         blockingEvents = new ArrayList<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now));
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now, null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1), null));
 
         List<DisabledDuration> pairs = odc.createBlockingDurations(blockingEvents);
         assertEquals(pairs.size(), 1);
@@ -680,9 +680,9 @@ public class TestBlockingCalculator extends JunctionTestSuite {
 
         //simple events closed clear -> disabled
         blockingEvents = new ArrayList<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now));
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
-        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now, null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1), null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2), null));
 
         pairs = odc.createBlockingDurations(blockingEvents);
         assertEquals(pairs.size(), 1);
@@ -693,9 +693,9 @@ public class TestBlockingCalculator extends JunctionTestSuite {
 
         //simple BUNDLE events closed clear -> disabled
         blockingEvents = new ArrayList<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now));
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
-        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2)));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now, null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1), null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(2), null));
 
         pairs = odc.createBlockingDurations(blockingEvents);
         assertEquals(pairs.size(), 1);
@@ -706,10 +706,10 @@ public class TestBlockingCalculator extends JunctionTestSuite {
 
         //two or more disableds in a row
         blockingEvents = new ArrayList<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now));
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(2)));
-        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(3)));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now, null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1), null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(2), null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(3), null));
 
         pairs = odc.createBlockingDurations(blockingEvents);
         assertEquals(pairs.size(), 1);
@@ -719,11 +719,11 @@ public class TestBlockingCalculator extends JunctionTestSuite {
         assertEquals(pairs.get(0).getEnd(), now.plusDays(3));
 
         blockingEvents = new ArrayList<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now));
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1)));
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(2)));
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(3)));
-        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(4)));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now, null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(1), null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(2), null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, now.plusDays(3), null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, now.plusDays(4), null));
 
         pairs = odc.createBlockingDurations(blockingEvents);
         assertEquals(pairs.size(), 1);
@@ -746,10 +746,10 @@ public class TestBlockingCalculator extends JunctionTestSuite {
         billingEvents.add(upgrade);
 
         final List<BlockingState> blockingEvents = new ArrayList<BlockingState>();
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, false, false, new LocalDate(2012, 7, 5).toDateTimeAtStartOfDay(DateTimeZone.UTC)));
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, new LocalDate(2012, 7, 15).toDateTimeAtStartOfDay(DateTimeZone.UTC)));
-        blockingEvents.add(new DefaultBlockingState(ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, new LocalDate(2012, 7, 25).toDateTimeAtStartOfDay(DateTimeZone.UTC)));
-        blockingEvents.add(new DefaultBlockingState(ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, new LocalDate(2012, 7, 25).toDateTimeAtStartOfDay(DateTimeZone.UTC)));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, false, false, new LocalDate(2012, 7, 5).toDateTimeAtStartOfDay(DateTimeZone.UTC), null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, new LocalDate(2012, 7, 15).toDateTimeAtStartOfDay(DateTimeZone.UTC), null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, DISABLED_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", true, true, true, new LocalDate(2012, 7, 25).toDateTimeAtStartOfDay(DateTimeZone.UTC), null));
+        blockingEvents.add(new DefaultBlockingState(UUID.randomUUID(),ovdId, CLEAR_BUNDLE, Type.SUBSCRIPTION_BUNDLE, "test", false, false, false, new LocalDate(2012, 7, 25).toDateTimeAtStartOfDay(DateTimeZone.UTC), null));
 
         Mockito.when(blockingApi.getBlockingHistory(bundleId1, internalCallContext)).thenReturn(blockingEvents);
 
diff --git a/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java b/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java
index 5366c5f..35edf31 100644
--- a/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java
+++ b/overdue/src/test/java/com/ning/billing/overdue/applicator/ApplicatorMockJunctionModule.java
@@ -85,6 +85,20 @@ public class ApplicatorMockJunctionModule extends MockJunctionModule {
                     return null;
                 }
 
+                @Override
+                public UUID getId() {
+                    return UUID.randomUUID();
+                }
+
+                @Override
+                public DateTime getCreatedDate() {
+                    return null;
+                }
+
+                @Override
+                public DateTime getUpdatedDate() {
+                    return null;
+                }
             };
         }
 
diff --git a/tenant/src/main/java/com/ning/billing/tenant/api/DefaultTenantKV.java b/tenant/src/main/java/com/ning/billing/tenant/api/DefaultTenantKV.java
index ece3445..9b67cdc 100644
--- a/tenant/src/main/java/com/ning/billing/tenant/api/DefaultTenantKV.java
+++ b/tenant/src/main/java/com/ning/billing/tenant/api/DefaultTenantKV.java
@@ -16,12 +16,19 @@
 package com.ning.billing.tenant.api;
 
 
-public class DefaultTenantKV  implements TenantKV {
+import java.util.UUID;
+
+import org.joda.time.DateTime;
+
+import com.ning.billing.util.entity.EntityBase;
+
+public class DefaultTenantKV  extends EntityBase implements TenantKV {
 
     private final String key;
     private final String value;
 
-    public DefaultTenantKV(final String key, final String value) {
+    public DefaultTenantKV(final UUID id, final String key, final String value, final DateTime createdDate, final DateTime updatedDate) {
+        super(id, createdDate, updatedDate);
         this.key = key;
         this.value = value;
     }
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java b/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java
index 16620e3..f17d01b 100644
--- a/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/DefaultTenantDao.java
@@ -115,7 +115,7 @@ public class DefaultTenantDao implements TenantDao {
 
     @Override
     public void addTenantKeyValue(final String key, final String value, final InternalCallContext context) {
-        tenantKVSqlDao.insertTenantKeyValue(key, value, context.getTenantRecordId(), context);
+        tenantKVSqlDao.insertTenantKeyValue(UUID.randomUUID().toString(), key, value, context.getTenantRecordId(), context);
     }
 
     @Override
diff --git a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantKVSqlDao.java b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantKVSqlDao.java
index 83b3d79..ae58d87 100644
--- a/tenant/src/main/java/com/ning/billing/tenant/dao/TenantKVSqlDao.java
+++ b/tenant/src/main/java/com/ning/billing/tenant/dao/TenantKVSqlDao.java
@@ -18,7 +18,9 @@ package com.ning.billing.tenant.dao;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.util.List;
+import java.util.UUID;
 
+import org.joda.time.DateTime;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.sqlobject.Bind;
 import org.skife.jdbi.v2.sqlobject.SqlQuery;
@@ -44,7 +46,7 @@ public interface TenantKVSqlDao extends Transactional<TenantKVSqlDao> {
     public List<TenantKV> getTenantValueForKey(@Bind("key") final String key, @Bind("tenantRecordId") Long tenantRecordId);
 
     @SqlUpdate
-    public void insertTenantKeyValue(@Bind("key") final String key, @Bind("value") final String value, @Bind("tenantRecordId") Long tenantRecordId, @InternalTenantContextBinder final InternalCallContext context);
+    public void insertTenantKeyValue(@Bind("id") String id, @Bind("key") final String key, @Bind("value") final String value, @Bind("tenantRecordId") Long tenantRecordId, @InternalTenantContextBinder final InternalCallContext context);
 
     @SqlUpdate
     public void deleteTenantKey(@Bind("key") final String key, @Bind("tenantRecordId") Long tenantRecordId);
@@ -54,9 +56,12 @@ public interface TenantKVSqlDao extends Transactional<TenantKVSqlDao> {
 
         @Override
         public TenantKV map(final int index, final ResultSet result, final StatementContext context) throws SQLException {
+            final UUID id = getUUID(result, "id");
             final String key = result.getString("t_key");
             final String value = result.getString("t_value");
-            return new DefaultTenantKV(key, value);
+            final DateTime createdDate = getDateTime(result, "created_date");
+            final DateTime updatedDate = getDateTime(result, "updated_date");
+            return new DefaultTenantKV(id, key, value, createdDate, updatedDate);
         }
     }
 }
diff --git a/tenant/src/main/resources/com/ning/billing/tenant/dao/TenantKVSqlDao.sql.stg b/tenant/src/main/resources/com/ning/billing/tenant/dao/TenantKVSqlDao.sql.stg
index 432267f..ce66a1a 100644
--- a/tenant/src/main/resources/com/ning/billing/tenant/dao/TenantKVSqlDao.sql.stg
+++ b/tenant/src/main/resources/com/ning/billing/tenant/dao/TenantKVSqlDao.sql.stg
@@ -3,6 +3,7 @@ group TenantKVSqlDao;
 
 tenantKVFields(prefix) ::= <<
     <prefix>record_id,
+    <prefix>id,
     <prefix>tenant_record_id,
     <prefix>t_key,
     <prefix>t_value,
@@ -14,7 +15,8 @@ tenantKVFields(prefix) ::= <<
 
 insertTenantKeyValue() ::= <<
    INSERT INTO tenant_kvs (
-        tenant_record_id
+      id
+      , tenant_record_id
       , t_key
       , t_value
       , created_date
@@ -22,7 +24,8 @@ insertTenantKeyValue() ::= <<
       , updated_date
       , updated_by
     ) VALUES (
-        :tenantRecordId
+      :id
+      , :tenantRecordId
       , :key
       , :value
       , :createdDate
@@ -52,4 +55,4 @@ deleteTenantKey() ::= <<
 
 test() ::= <<
     SELECT 1 FROM tenants;
->>
\ No newline at end of file
+>>
diff --git a/tenant/src/main/resources/com/ning/billing/tenant/ddl.sql b/tenant/src/main/resources/com/ning/billing/tenant/ddl.sql
index a8a7911..4096d11 100644
--- a/tenant/src/main/resources/com/ning/billing/tenant/ddl.sql
+++ b/tenant/src/main/resources/com/ning/billing/tenant/ddl.sql
@@ -19,6 +19,7 @@ CREATE UNIQUE INDEX tenants_api_key ON tenants(api_key);
 DROP TABLE IF EXISTS tenant_kvs;
 CREATE TABLE tenant_kvs (
    record_id int(11) unsigned NOT NULL AUTO_INCREMENT,
+   id char(36) NOT NULL,
    tenant_record_id int(11) unsigned default null,
    t_key varchar(64) NOT NULL,
    t_value varchar(1024) NOT NULL,
@@ -28,4 +29,4 @@ CREATE TABLE tenant_kvs (
    updated_by varchar(50) DEFAULT NULL,
    PRIMARY KEY(record_id)
 ) ENGINE=innodb;
-CREATE INDEX tenant_kvs_key ON tenant_kvs(tenant_record_id, t_key);
\ No newline at end of file
+CREATE INDEX tenant_kvs_key ON tenant_kvs(tenant_record_id, t_key);
diff --git a/util/src/main/java/com/ning/billing/util/audit/api/DefaultAuditUserApi.java b/util/src/main/java/com/ning/billing/util/audit/api/DefaultAuditUserApi.java
index 8a91fc2..0429e67 100644
--- a/util/src/main/java/com/ning/billing/util/audit/api/DefaultAuditUserApi.java
+++ b/util/src/main/java/com/ning/billing/util/audit/api/DefaultAuditUserApi.java
@@ -69,7 +69,7 @@ public class DefaultAuditUserApi implements AuditUserApi {
         final Map<UUID, List<AuditLog>> subscriptionsAuditLogs = new HashMap<UUID, List<AuditLog>>();
         final Map<UUID, List<AuditLog>> subscriptionEventsAuditLogs = new HashMap<UUID, List<AuditLog>>();
         for (final BundleTimeline bundle : bundles) {
-            bundlesAuditLogs.put(bundle.getBundleId(), getAuditLogs(bundle.getBundleId(), ObjectType.BUNDLE, auditLevel, context));
+            bundlesAuditLogs.put(bundle.getId(), getAuditLogs(bundle.getId(), ObjectType.BUNDLE, auditLevel, context));
             for (final SubscriptionTimeline subscriptionTimeline : bundle.getSubscriptions()) {
                 subscriptionsAuditLogs.put(subscriptionTimeline.getId(), getAuditLogs(subscriptionTimeline.getId(), ObjectType.SUBSCRIPTION, auditLevel, context));
                 for (final ExistingEvent event : subscriptionTimeline.getExistingEvents()) {
diff --git a/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java b/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java
index 98257fa..4458801 100644
--- a/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java
+++ b/util/src/main/java/com/ning/billing/util/customfield/StringCustomField.java
@@ -18,9 +18,10 @@ package com.ning.billing.util.customfield;
 
 import java.util.UUID;
 
-import com.ning.billing.util.entity.UpdatableEntityBase;
+import com.ning.billing.util.entity.Entity;
+import com.ning.billing.util.entity.EntityBase;
 
-public class StringCustomField extends UpdatableEntityBase implements CustomField {
+public class StringCustomField extends EntityBase implements CustomField, Entity {
     private final String name;
     private String value;
 
diff --git a/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntityDao.java b/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntityDao.java
index e04c33c..4b9e0b2 100644
--- a/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntityDao.java
+++ b/util/src/main/java/com/ning/billing/util/entity/dao/UpdatableEntityDao.java
@@ -18,9 +18,8 @@ package com.ning.billing.util.entity.dao;
 
 import com.ning.billing.util.callcontext.InternalCallContext;
 import com.ning.billing.util.entity.EntityPersistenceException;
-import com.ning.billing.util.entity.UpdatableEntity;
 
-public interface UpdatableEntityDao<T extends UpdatableEntity> extends EntityDao<T> {
+public interface UpdatableEntityDao<T> extends EntityDao {
 
     public void update(T entity, InternalCallContext context) throws EntityPersistenceException;
 }
diff --git a/util/src/main/java/com/ning/billing/util/svcapi/junction/DefaultBlockingState.java b/util/src/main/java/com/ning/billing/util/svcapi/junction/DefaultBlockingState.java
index 2606ee1..d1c9853 100644
--- a/util/src/main/java/com/ning/billing/util/svcapi/junction/DefaultBlockingState.java
+++ b/util/src/main/java/com/ning/billing/util/svcapi/junction/DefaultBlockingState.java
@@ -22,9 +22,11 @@ import org.joda.time.DateTime;
 
 import com.ning.billing.junction.api.Blockable;
 import com.ning.billing.junction.api.BlockingState;
+import com.ning.billing.util.entity.Entity;
+import com.ning.billing.util.entity.EntityBase;
 
 
-public class DefaultBlockingState implements BlockingState {
+public class DefaultBlockingState extends EntityBase implements BlockingState {
 
     public static final String CLEAR_STATE_NAME = "__KILLBILL__CLEAR__OVERDUE_STATE__";
 
@@ -46,34 +48,18 @@ public class DefaultBlockingState implements BlockingState {
         return clearState;
     }
 
-    public DefaultBlockingState(final UUID blockingId,
-                                final String stateName,
-                                final Blockable.Type type,
-                                final String service,
-                                final boolean blockChange,
-                                final boolean blockEntitlement,
-                                final boolean blockBilling
-                               ) {
-        this(blockingId,
-             stateName,
-             type,
-             service,
-             blockChange,
-             blockEntitlement,
-             blockBilling,
-             null);
-    }
 
-    public DefaultBlockingState(final UUID blockingId,
+    public DefaultBlockingState(final UUID id,
+                                final UUID blockingId,
                                 final String stateName,
                                 final Blockable.Type type,
                                 final String service,
                                 final boolean blockChange,
                                 final boolean blockEntitlement,
                                 final boolean blockBilling,
-                                final DateTime timestamp
-                               ) {
-        super();
+                                final DateTime timestamp,
+                                final DateTime createDate) {
+        super(id, createDate, null);
         this.blockingId = blockingId;
         this.stateName = stateName;
         this.service = service;
@@ -84,6 +70,26 @@ public class DefaultBlockingState implements BlockingState {
         this.timestamp = timestamp;
     }
 
+    public DefaultBlockingState(final UUID blockingId,
+                                 final String stateName,
+                                 final Blockable.Type type,
+                                 final String service,
+                                 final boolean blockChange,
+                                 final boolean blockEntitlement,
+                                 final boolean blockBilling) {
+        this(UUID.randomUUID(),
+             blockingId,
+             stateName,
+             type,
+             service,
+             blockChange,
+             blockEntitlement,
+             blockBilling,
+             null,
+             null);
+    }
+
+
     public UUID getBlockedId() {
         return blockingId;
     }
@@ -245,6 +251,4 @@ public class DefaultBlockingState implements BlockingState {
                 + service + ", blockChange=" + blockChange + ", blockEntitlement=" + blockEntitlement
                 + ", blockBilling=" + blockBilling + ", timestamp=" + timestamp + "]";
     }
-
-
 }
diff --git a/util/src/test/java/com/ning/billing/util/audit/api/TestDefaultAuditUserApi.java b/util/src/test/java/com/ning/billing/util/audit/api/TestDefaultAuditUserApi.java
index 7f45d5a..d1fef2c 100644
--- a/util/src/test/java/com/ning/billing/util/audit/api/TestDefaultAuditUserApi.java
+++ b/util/src/test/java/com/ning/billing/util/audit/api/TestDefaultAuditUserApi.java
@@ -75,7 +75,7 @@ public class TestDefaultAuditUserApi extends AuditLogsTestBase {
         final List<BundleTimeline> bundles = new ArrayList<BundleTimeline>();
         for (final UUID objectId : objectIds) {
             final BundleTimeline entity = Mockito.mock(BundleTimeline.class);
-            Mockito.when(entity.getBundleId()).thenReturn(objectId);
+            Mockito.when(entity.getId()).thenReturn(objectId);
             bundles.add(entity);
         }
 
diff --git a/util/src/test/java/com/ning/billing/util/export/dao/TestDatabaseExportDao.java b/util/src/test/java/com/ning/billing/util/export/dao/TestDatabaseExportDao.java
index db9465e..f5bdecb 100644
--- a/util/src/test/java/com/ning/billing/util/export/dao/TestDatabaseExportDao.java
+++ b/util/src/test/java/com/ning/billing/util/export/dao/TestDatabaseExportDao.java
@@ -61,11 +61,13 @@ public class TestDatabaseExportDao extends UtilTestSuiteWithEmbeddedDB {
         getMysqlTestingHelper().getDBI().withHandle(new HandleCallback<Void>() {
             @Override
             public Void withHandle(final Handle handle) throws Exception {
+                handle.execute("drop table if exists " + tableNameA);
                 handle.execute("create table " + tableNameA + "(record_id int(11) unsigned not null auto_increment," +
                                "a_column char default 'a'," +
                                "account_record_id int(11) unsigned not null," +
                                "tenant_record_id int(11) unsigned default 0," +
                                "primary key(record_id)) engine=innodb;");
+                handle.execute("drop table if exists " + tableNameB);
                 handle.execute("create table " + tableNameB + "(record_id int(11) unsigned not null auto_increment," +
                                "b_column char default 'b'," +
                                "account_record_id int(11) unsigned not null," +