Hibernate SVN: r11459 - in trunk/HibernateExt/shards/src: java/org/hibernate/shards/session and 3 other directories.
by hibernate-commits@lists.jboss.org
Author: max.ross
Date: 2007-05-02 03:38:01 -0400 (Wed, 02 May 2007)
New Revision: 11459
Added:
trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/model/ModelIntegrationTest.java
Modified:
trunk/HibernateExt/shards/src/java/org/hibernate/shards/Shard.java
trunk/HibernateExt/shards/src/java/org/hibernate/shards/ShardImpl.java
trunk/HibernateExt/shards/src/java/org/hibernate/shards/session/ShardedSessionImpl.java
trunk/HibernateExt/shards/src/test/org/hibernate/shards/NonPermutedTests.java
trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/model/ModelPermutedIntegrationTest.java
trunk/HibernateExt/shards/src/test/org/hibernate/shards/session/ShardedSessionImplTest.java
Log:
Fix bugs in update, delete, and saveOrUpdate.
Add support for objects with ids that are base types.
Modified: trunk/HibernateExt/shards/src/java/org/hibernate/shards/Shard.java
===================================================================
--- trunk/HibernateExt/shards/src/java/org/hibernate/shards/Shard.java 2007-05-02 06:23:27 UTC (rev 11458)
+++ trunk/HibernateExt/shards/src/java/org/hibernate/shards/Shard.java 2007-05-02 07:38:01 UTC (rev 11459)
@@ -18,6 +18,11 @@
package org.hibernate.shards;
+import org.hibernate.Criteria;
+import org.hibernate.LockMode;
+import org.hibernate.Query;
+import org.hibernate.classic.Session;
+import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.shards.criteria.CriteriaEvent;
import org.hibernate.shards.criteria.CriteriaId;
import org.hibernate.shards.criteria.ShardedCriteria;
@@ -26,12 +31,6 @@
import org.hibernate.shards.query.ShardedQuery;
import org.hibernate.shards.session.OpenSessionEvent;
-import org.hibernate.Criteria;
-import org.hibernate.LockMode;
-import org.hibernate.Query;
-import org.hibernate.classic.Session;
-import org.hibernate.engine.SessionFactoryImplementor;
-
import java.io.Serializable;
import java.util.List;
import java.util.Set;
@@ -188,4 +187,8 @@
* @see Query#uniqueResult()
*/
Object uniqueResult(QueryId queryId);
+
+ void merge(Object object);
+
+ void merge(String entityName, Object object);
}
Modified: trunk/HibernateExt/shards/src/java/org/hibernate/shards/ShardImpl.java
===================================================================
--- trunk/HibernateExt/shards/src/java/org/hibernate/shards/ShardImpl.java 2007-05-02 06:23:27 UTC (rev 11458)
+++ trunk/HibernateExt/shards/src/java/org/hibernate/shards/ShardImpl.java 2007-05-02 07:38:01 UTC (rev 11459)
@@ -18,6 +18,12 @@
package org.hibernate.shards;
+import org.hibernate.Criteria;
+import org.hibernate.Interceptor;
+import org.hibernate.LockMode;
+import org.hibernate.Query;
+import org.hibernate.classic.Session;
+import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.shards.criteria.CriteriaEvent;
import org.hibernate.shards.criteria.CriteriaId;
import org.hibernate.shards.criteria.ShardedCriteria;
@@ -30,13 +36,6 @@
import org.hibernate.shards.util.Preconditions;
import org.hibernate.shards.util.Sets;
-import org.hibernate.Criteria;
-import org.hibernate.Interceptor;
-import org.hibernate.LockMode;
-import org.hibernate.Query;
-import org.hibernate.classic.Session;
-import org.hibernate.engine.SessionFactoryImplementor;
-
import java.io.Serializable;
import java.util.Collections;
import java.util.LinkedList;
@@ -382,5 +381,12 @@
events.addLast(event);
}
+ public void merge(Object object) {
+ establishSession().merge(object);
+ }
+
+ public void merge(String entityName, Object object) {
+ establishSession().merge(entityName, object);
+ }
}
Modified: trunk/HibernateExt/shards/src/java/org/hibernate/shards/session/ShardedSessionImpl.java
===================================================================
--- trunk/HibernateExt/shards/src/java/org/hibernate/shards/session/ShardedSessionImpl.java 2007-05-02 06:23:27 UTC (rev 11458)
+++ trunk/HibernateExt/shards/src/java/org/hibernate/shards/session/ShardedSessionImpl.java 2007-05-02 07:38:01 UTC (rev 11459)
@@ -18,14 +18,34 @@
package org.hibernate.shards.session;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.hibernate.CacheMode;
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.Filter;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.LockMode;
+import org.hibernate.Query;
+import org.hibernate.ReplicationMode;
+import org.hibernate.SQLQuery;
+import org.hibernate.SessionException;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.TransientObjectException;
+import org.hibernate.classic.Session;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.proxy.HibernateProxy;
import org.hibernate.shards.CrossShardAssociationException;
import org.hibernate.shards.Shard;
import org.hibernate.shards.ShardId;
import org.hibernate.shards.ShardImpl;
import org.hibernate.shards.ShardOperation;
import org.hibernate.shards.ShardedTransaction;
-import org.hibernate.shards.util.Lists;
-import org.hibernate.shards.util.Sets;
import org.hibernate.shards.criteria.CriteriaFactoryImpl;
import org.hibernate.shards.criteria.CriteriaId;
import org.hibernate.shards.criteria.ShardedCriteriaImpl;
@@ -43,32 +63,11 @@
import org.hibernate.shards.strategy.selection.ShardResolutionStrategyDataImpl;
import org.hibernate.shards.transaction.ShardedTransactionImpl;
import org.hibernate.shards.util.Iterables;
+import org.hibernate.shards.util.Lists;
import org.hibernate.shards.util.Maps;
import org.hibernate.shards.util.Pair;
import org.hibernate.shards.util.Preconditions;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.hibernate.CacheMode;
-import org.hibernate.Criteria;
-import org.hibernate.EntityMode;
-import org.hibernate.Filter;
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.LockMode;
-import org.hibernate.Query;
-import org.hibernate.ReplicationMode;
-import org.hibernate.SQLQuery;
-import org.hibernate.SessionException;
-import org.hibernate.SessionFactory;
-import org.hibernate.Transaction;
-import org.hibernate.TransientObjectException;
-import org.hibernate.classic.Session;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.metadata.ClassMetadata;
-import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.shards.util.Sets;
import org.hibernate.stat.SessionStatistics;
import org.hibernate.type.Type;
@@ -579,16 +578,14 @@
}
public Serializable save(String entityName, Object object) throws HibernateException {
- ShardId shardId;
- if(contains(object)) {
- shardId = getShardIdForObject(object);
- } else {
+ ShardId shardId = getShardIdForObject(object);
+ if(shardId == null) {
shardId = selectShardIdForNewObject(object);
}
Preconditions.checkNotNull(shardId);
setCurrentSubgraphShardId(shardId);
log.debug(String.format("Saving object of type %s to shard %s", object.getClass(), shardId));
- return shardIdsToShards.get(shardId).save(entityName, object);
+ return shardIdsToShards.get(shardId).save(entityName, object);
}
ShardId selectShardIdForNewObject(Object obj) {
@@ -725,83 +722,112 @@
shard.saveOrUpdate(entityName, object);
}
- public void update(Shard shard, Object object) {
- shard.update(entityName, object);
+ public void merge(Shard shard, Object object) {
+ shard.merge(entityName, object);
}
};
applySaveOrUpdateOperation(op, object);
}
void applySaveOrUpdateOperation(SaveOrUpdateOperation op, Object object) {
- List<ShardId> saveOrUpdateShardIds = determineShardIdsForObjectThatMightAlreadyExist(object);
- if(saveOrUpdateShardIds.size() == 1) {
- /**
- * if there's only 1 shard id we don't need to worry about whether this is
- * a save or an update because we know we've got the right shard.
- * We'll let that shard figure out what the right thing to do is
- */
- ShardId shardId = saveOrUpdateShardIds.get(0);
- setCurrentSubgraphShardId(shardId);
+ ShardId shardId = getShardIdForObject(object);
+ if(shardId != null) {
+ // attached object
op.saveOrUpdate(shardIdsToShards.get(shardId), object);
- } else {
- /**
- * If we've got multiple shard ids we know it's an update. However,
- * we can't call saveOrUpdate() on multiple shards because if it
- * already exists and we call saveOrUpdate() on the wrong shard we're
- * going to end up with the same object in multiple shards, and that's
- * really bad. Instead we'll just figure out the single shard on which
- * the object resides and perform the update there.
- */
- ShardId shardId = getShardIdForObject(object);
- setCurrentSubgraphShardId(shardId);
- Shard shard = shardIdsToShards.get(shardId);
- op.update(shard, object);
+ return;
}
- }
+ List<Shard> potentialShards = determineShardsObjectViaResolutionStrategy(object);
+ if(potentialShards.size() == 1) {
+ op.saveOrUpdate(potentialShards.get(0), object);
+ return;
+ }
- List<ShardId> determineShardIdsForObjectThatMightAlreadyExist(Object object) {
+ /**
+ * Too bad, we've got a detached object that could be on more than 1 shard.
+ * The only safe way to handle this is to try and lookup the object, and if
+ * it exists, do a merge, and if it doesn't, do a save.
+ */
Serializable id = extractId(object);
- if(id == null) {
- ShardId shardId = selectShardIdForNewObject(object);
- // if there's no id then it's clearly a save operation
- return Collections.singletonList(shardId);
+ if(id != null) {
+ Object persistent = get(object.getClass(), id);
+ if(persistent != null) {
+ shardId = getShardIdForObject(persistent);
+ }
}
- /**
- * there is an id so it might be a save operation (user provided the id)
- * or it might be an update
- */
- ShardResolutionStrategyData srsd = new ShardResolutionStrategyDataImpl(object.getClass(), id);
- return selectShardIdsFromShardResolutionStrategyData(srsd);
+ if(shardId != null) {
+ op.merge(shardIdsToShards.get(shardId), object);
+ } else {
+ save(object);
+ }
}
- private Serializable extractId(Object object) {
+ Serializable extractId(Object object) {
ClassMetadata cmd = shardedSessionFactory.getClassMetadata(object.getClass());
// I'm just guessing about the EntityMode
return cmd.getIdentifier(object, EntityMode.POJO);
}
- public void update(Object object) throws HibernateException {
- /*
- * we might get back multiple shards if there isn't a sure-fire
- * way to derive the shard from the object, but since the object
- * only exists on one shard there's no harm in trying to update
- * it multiple places because the update will only succeed in one place.
+ private interface UpdateOperation {
+ void update(Shard shard, Object object);
+ void merge(Shard shard, Object object);
+ }
+
+ private static final UpdateOperation SIMPLE_UPDATE_OPERATION =
+ new UpdateOperation() {
+ public void update(Shard shard, Object object) {
+ shard.update(object);
+ }
+
+ public void merge(Shard shard, Object object) {
+ shard.merge(object);
+ }
+ };
+
+ private void applyUpdateOperation(UpdateOperation op, Object object) {
+ ShardId shardId = getShardIdForObject(object);
+ if(shardId != null) {
+ // attached object
+ op.update(shardIdsToShards.get(shardId), object);
+ return;
+ }
+ List<Shard> potentialShards = determineShardsObjectViaResolutionStrategy(object);
+ if(potentialShards.size() == 1) {
+ op.update(potentialShards.get(0), object);
+ return;
+ }
+ /**
+ * Too bad, we've got a detached object that could be on more than 1 shard.
+ * The only safe way to perform the update is to load the object and then
+ * do a merge.
*/
- // What about exceptions?
- for(Shard shard : determineShardsForObjectThatExists(object)) {
- shard.update(object);
- }
+ Object persistent = get(object.getClass(), extractId(object));
+ shardId = getShardIdForObject(persistent);
+ op.merge(shardIdsToShards.get(shardId), object);
}
- public void update(String entityName, Object object)
+ public void update(Object object) throws HibernateException {
+ applyUpdateOperation(SIMPLE_UPDATE_OPERATION, object);
+ }
+
+ public void update(final String entityName, Object object)
throws HibernateException {
- for(Shard shard : determineShardsForObjectThatExists(object)) {
- shard.update(entityName, object);
- }
+ UpdateOperation op = new UpdateOperation() {
+ public void update(Shard shard, Object object) {
+ shard.update(entityName, object);
+ }
+
+ public void merge(Shard shard, Object object) {
+ shard.merge(entityName, object);
+ }
+ };
+ applyUpdateOperation(op, object);
}
- private List<Shard> determineShardsForObjectThatExists(Object object) {
+ List<Shard> determineShardsObjectViaResolutionStrategy(Object object) {
Serializable id = extractId(object);
+ if(id == null) {
+ return Collections.emptyList();
+ }
ShardResolutionStrategyData srsd = new ShardResolutionStrategyDataImpl(object.getClass(), id);
List<ShardId> shardIds = selectShardIdsFromShardResolutionStrategyData(srsd);
return shardIdListToShardList(shardIds);
@@ -837,32 +863,63 @@
throw new UnsupportedOperationException();
}
- public void delete(Object object) throws HibernateException {
+ private interface DeleteOperation {
+ void delete(Shard shard, Object object);
+ }
+
+ private void applyDeleteOperation(DeleteOperation op, Object object) {
+ ShardId shardId = getShardIdForObject(object);
+ if(shardId != null) {
+ // attached object
+ op.delete(shardIdsToShards.get(shardId), object);
+ return;
+ }
/**
- * we might get back multiple shards if there isn't a sure-fire
- * way to derive the shard from the object. It turns out that if you have an
+ * Detached object.
+ * We can't just try to delete on each shard because if you have an
* object associated with Session x and you try to delete that object in
- * Sessoin y, and if that object has persistent collections, Hibernate will
+ * Session y, and if that object has persistent collections, Hibernate will
* blow up because it will try to associate the persistent collection with
* a different Session as part of the cascade. In order to avoid this we
- * need to be precise about the shard on which we perform the delete
+ * need to be precise about the shard on which we perform the delete.
+ *
+ * First let's see if we can derive the shard just from the object's id.
*/
-
- // What about exceptions?
- List<Shard> potentialShards = determineShardsForObjectThatExists(object);
+ List<Shard> potentialShards = determineShardsObjectViaResolutionStrategy(object);
if(potentialShards.size() == 1) {
- potentialShards.get(0).delete(object);
+ op.delete(potentialShards.get(0), object);
return;
}
- ShardId shardId = getShardIdForObject(object, potentialShards);
- shardIdsToShards.get(shardId).delete(object);
+ /**
+ * Too bad, we've got a detached object that could be on more than 1 shard.
+ * The only safe way to perform the delete is to load the object before
+ * deleting.
+ */
+ Object persistent = get(object.getClass(), extractId(object));
+ shardId = getShardIdForObject(persistent);
+ op.delete(shardIdsToShards.get(shardId), persistent);
}
- public void delete(String entityName, Object object)
+ private static final DeleteOperation SIMPLE_DELETE_OPERATION =
+ new DeleteOperation() {
+
+ public void delete(Shard shard, Object object) {
+ shard.delete(object);
+ }
+ };
+
+ public void delete(Object object) throws HibernateException {
+ applyDeleteOperation(SIMPLE_DELETE_OPERATION, object);
+ }
+
+ public void delete(final String entityName, Object object)
throws HibernateException {
- for(Shard shard : determineShardsForObjectThatExists(object)) {
- shard.delete(entityName, object);
- }
+ DeleteOperation op = new DeleteOperation() {
+ public void delete(Shard shard, Object object) {
+ shard.delete(entityName, object);
+ }
+ };
+ applyDeleteOperation(op, object);
}
/**
@@ -1258,7 +1315,7 @@
interface SaveOrUpdateOperation {
void saveOrUpdate(Shard shard, Object object);
- void update(Shard shard, Object object);
+ void merge(Shard shard, Object object);
}
private static final SaveOrUpdateOperation SAVE_OR_UPDATE_SIMPLE = new SaveOrUpdateOperation() {
@@ -1266,8 +1323,8 @@
shard.saveOrUpdate(object);
}
- public void update(Shard shard, Object object) {
- shard.update(object);
+ public void merge(Shard shard, Object object) {
+ shard.merge(object);
}
};
@@ -1293,6 +1350,7 @@
}
public ShardId getShardIdForObject(Object obj, List<Shard> shardsToConsider) {
+ // TODO(maxr) optimize this by keeping an identity map of objects to shardId
Shard shard = getShardForObject(obj, shardsToConsider);
if(shard == null) {
return null;
Modified: trunk/HibernateExt/shards/src/test/org/hibernate/shards/NonPermutedTests.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/NonPermutedTests.java 2007-05-02 06:23:27 UTC (rev 11458)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/NonPermutedTests.java 2007-05-02 07:38:01 UTC (rev 11459)
@@ -65,6 +65,7 @@
classes.add(org.hibernate.shards.id.ShardedTableHiLoGeneratorTest.class);
classes.add(org.hibernate.shards.id.ShardedUUIDGeneratorTest.class);
classes.add(org.hibernate.shards.integration.model.MemoryLeakTest.class);
+ classes.add(org.hibernate.shards.integration.model.ModelIntegrationTest.class);
classes.add(org.hibernate.shards.loadbalance.RoundRobinShardLoadBalancerTest.class);
classes.add(org.hibernate.shards.query.SetBigDecimalEventTest.class);
classes.add(org.hibernate.shards.query.SetBigIntegerEventTest.class);
Added: trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/model/ModelIntegrationTest.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/model/ModelIntegrationTest.java (rev 0)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/model/ModelIntegrationTest.java 2007-05-02 07:38:01 UTC (rev 11459)
@@ -0,0 +1,48 @@
+/**
+ * Copyright (C) 2007 Google Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+package org.hibernate.shards.integration.model;
+
+import org.hibernate.shards.integration.BaseShardingIntegrationTestCase;
+import org.hibernate.shards.model.IdIsBaseType;
+
+/**
+ * @author maxr(a)google.com (Max Ross)
+ */
+public class ModelIntegrationTest extends BaseShardingIntegrationTestCase {
+
+ public void testSaveIdIsBaseType() {
+ IdIsBaseType hli = new IdIsBaseType();
+ session.beginTransaction();
+ hli.setValue("yamma");
+ session.save(hli);
+ commitAndResetSession();
+ hli = reload(hli);
+ assertNotNull(hli);
+ }
+
+ public void testSaveOrUpdateIdIsBasetype() {
+ IdIsBaseType hli = new IdIsBaseType();
+ session.beginTransaction();
+ hli.setValue("yamma");
+ session.saveOrUpdate(hli);
+ commitAndResetSession();
+ hli = reload(hli);
+ assertNotNull(hli);
+ }
+
+}
Modified: trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/model/ModelPermutedIntegrationTest.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/model/ModelPermutedIntegrationTest.java 2007-05-02 06:23:27 UTC (rev 11458)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/model/ModelPermutedIntegrationTest.java 2007-05-02 07:38:01 UTC (rev 11459)
@@ -18,6 +18,12 @@
package org.hibernate.shards.integration.model;
+import org.hibernate.HibernateException;
+import org.hibernate.SessionFactory;
+import org.hibernate.TransactionException;
+import org.hibernate.classic.Session;
+import org.hibernate.criterion.Projections;
+import org.hibernate.proxy.HibernateProxy;
import org.hibernate.shards.ShardId;
import org.hibernate.shards.integration.BaseShardingIntegrationTestCase;
import org.hibernate.shards.integration.MemoryLeakPlugger;
@@ -46,13 +52,6 @@
import org.hibernate.shards.util.Maps;
import org.hibernate.shards.util.Sets;
-import org.hibernate.HibernateException;
-import org.hibernate.SessionFactory;
-import org.hibernate.TransactionException;
-import org.hibernate.classic.Session;
-import org.hibernate.criterion.Projections;
-import org.hibernate.proxy.HibernateProxy;
-
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
@@ -82,7 +81,7 @@
@Override
protected IdGenType getIdGenType() {
- return IdGenType.SHARD_UUID;
+ return IdGenType.SIMPLE;
}
*/
@@ -106,8 +105,7 @@
session.save(b);
buildings.add(b);
}
- session.getTransaction().commit();
- resetSession();
+ commitAndResetSession();
List<Integer> counts = session.createCriteria(Building.class).setProjection(Projections.rowCount()).list();
int total = 0;
for(Integer count : counts) {
@@ -150,8 +148,7 @@
for(List<Serializable> idList : shards.values()) {
assertEquals(2, idList.size());
}
- session.getTransaction().commit();
- resetSession();
+ commitAndResetSession();
session.beginTransaction();
for(Building b : buildings) {
Building bReloaded = reloadAssertNotNull(b);
@@ -169,8 +166,7 @@
// now let's get rid of the buildings
session.delete(bReloaded);
}
- session.getTransaction().commit();
- resetSession();
+ commitAndResetSession();
for(Building b : buildings) {
assertNull(reload(b));
for(Floor f : b.getFloors()) {
@@ -179,20 +175,36 @@
}
}
- public void testSaveOrUpdate() {
+ public void testSaveOrUpdateAttached() {
session.beginTransaction();
Building b = building("b");
floor(b, 23);
- session.save(b);
- session.getTransaction().commit();
- resetSession();
+ session.saveOrUpdate(b);
+ commitAndResetSession();
session.beginTransaction();
b = reload(b);
b.setName("b2");
session.saveOrUpdate(b);
- session.getTransaction().commit();
+ commitAndResetSession();
+ b = reload(b);
+ assertEquals("b2", b.getName());
}
+ public void testSaveOrUpdateDetached() {
+ session.beginTransaction();
+ Building b = building("b");
+ floor(b, 23);
+ session.saveOrUpdate(b);
+ commitAndResetSession();
+ // let's do saveOrUpdate on a detached entity
+ Building transientB = building("b2");
+ transientB.setBuildingId(b.getBuildingId());
+ session.saveOrUpdate(transientB);
+ commitAndResetSession();
+ b = reload(b);
+ assertEquals("b2", b.getName());
+ }
+
public void testSavingOneToManyChildViaCascade() {
session.beginTransaction();
Building b = building("awesome building");
@@ -837,6 +849,60 @@
}
}
+ public void testUpdateOfAttachedEntity() {
+ session.beginTransaction();
+ Building b = building("b1");
+ session.save(b);
+ commitAndResetSession();
+ b = reload(b);
+ b.setName("other name");
+ session.update(b);
+ commitAndResetSession();
+ b = reload(b);
+ assertEquals("other name", b.getName());
+ }
+
+ // calling update on a detached entity should actually result in a merge
+ public void testUpdateOfDetachedEntity() {
+ session.beginTransaction();
+ Building b = building("b1");
+ session.save(b);
+ commitAndResetSession();
+ Building transientB = building("a different name");
+ transientB.setBuildingId(b.getBuildingId());
+ session.update(transientB);
+ commitAndResetSession();
+ b = (Building) session.get(Building.class, transientB.getBuildingId());
+ assertNotNull(b);
+ assertEquals("a different name", b.getName());
+ }
+
+ public void testDeleteOfAttachedEntity() {
+ session.beginTransaction();
+ Building b = building("b1");
+ session.save(b);
+ commitAndResetSession();
+ b = reload(b);
+ session.delete(b);
+ commitAndResetSession();
+ b = reload(b);
+ assertNull(b);
+ }
+
+ public void testDeleteOfDetachedEntity() {
+ session.beginTransaction();
+ Building b = building("b1");
+ session.save(b);
+ commitAndResetSession();
+ Building detached = new Building();
+ detached.setBuildingId(b.getBuildingId());
+ detached.setName("harold");
+ session.delete(detached);
+ commitAndResetSession();
+ b = reload(b);
+ assertNull(b);
+ }
+
// this is a really good way to shake out synchronization bugs
public void xtestOverAndOver() throws Exception {
final boolean[] go = {true};
Modified: trunk/HibernateExt/shards/src/test/org/hibernate/shards/session/ShardedSessionImplTest.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/session/ShardedSessionImplTest.java 2007-05-02 06:23:27 UTC (rev 11458)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/session/ShardedSessionImplTest.java 2007-05-02 07:38:01 UTC (rev 11459)
@@ -18,15 +18,23 @@
package org.hibernate.shards.session;
-import org.hibernate.shards.defaultmock.ClassMetadataDefaultMock;
-import org.hibernate.shards.defaultmock.InterceptorDefaultMock;
-import org.hibernate.shards.defaultmock.SessionFactoryDefaultMock;
-import org.hibernate.shards.defaultmock.TypeDefaultMock;
+import junit.framework.TestCase;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.Session;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.metadata.ClassMetadata;
import org.hibernate.shards.Shard;
import org.hibernate.shards.ShardDefaultMock;
import org.hibernate.shards.ShardId;
import org.hibernate.shards.ShardImpl;
import org.hibernate.shards.ShardedSessionFactoryDefaultMock;
+import org.hibernate.shards.defaultmock.ClassMetadataDefaultMock;
+import org.hibernate.shards.defaultmock.InterceptorDefaultMock;
+import org.hibernate.shards.defaultmock.SessionFactoryDefaultMock;
+import org.hibernate.shards.defaultmock.TypeDefaultMock;
import org.hibernate.shards.engine.ShardedSessionFactoryImplementor;
import org.hibernate.shards.strategy.ShardStrategy;
import org.hibernate.shards.strategy.ShardStrategyDefaultMock;
@@ -36,17 +44,9 @@
import org.hibernate.shards.util.Maps;
import org.hibernate.shards.util.Pair;
import org.hibernate.shards.util.Sets;
-
-import junit.framework.TestCase;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.Session;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.metadata.ClassMetadata;
import org.hibernate.type.Type;
+import java.io.Serializable;
import java.sql.Connection;
import java.util.Collections;
import java.util.List;
@@ -75,35 +75,62 @@
}
public void testApplySaveOrUpdateOperation() {
- final List[] listToReturn = { Lists.newArrayList(new ShardId(0)) };
+ final List<ShardId> shardIdToReturn = Lists.newArrayList(new ShardId(0));
+ final List<Shard> shardListToReturn = Lists.<Shard>newArrayList(new ShardDefaultMock());
+ final Serializable[] idToReturn = {null};
+ final boolean[] saveCalled = {false};
ShardedSessionImpl ssi = new MyShardedSessionImpl() {
@Override
- List<ShardId> determineShardIdsForObjectThatMightAlreadyExist(Object object) {
- return listToReturn[0];
+ public ShardId getShardIdForObject(Object obj) {
+ return shardIdToReturn.get(0);
}
+
+ List<Shard> determineShardsObjectViaResolutionStrategy(Object object) {
+ return shardListToReturn;
+ }
+
+ Serializable extractId(Object object) {
+ return idToReturn[0];
+ }
+
+ public Serializable save(String entityName, Object object)
+ throws HibernateException {
+ saveCalled[0] = true;
+ return null;
+ }
};
final boolean[] saveOrUpdateCalled = { false };
- final boolean[] updateCalled = { false };
+ final boolean[] mergeCalled = { false };
ShardedSessionImpl.SaveOrUpdateOperation op = new ShardedSessionImpl.SaveOrUpdateOperation() {
public void saveOrUpdate(Shard shard, Object object) {
saveOrUpdateCalled[0] = true;
}
- public void update(Shard shard, Object object) {
- updateCalled[0] = true;
+ public void merge(Shard shard, Object object) {
+ mergeCalled[0] = true;
}
+
};
ssi.applySaveOrUpdateOperation(op, null);
assertTrue(saveOrUpdateCalled[0]);
- assertFalse(updateCalled[0]);
+ assertFalse(mergeCalled[0]);
+ shardIdToReturn.set(0, null);
+ saveOrUpdateCalled[0] = false;
+ ssi.applySaveOrUpdateOperation(op, null);
+ assertTrue(saveOrUpdateCalled[0]);
+ assertFalse(mergeCalled[0]);
+ shardIdToReturn.set(0, null);
saveOrUpdateCalled[0] = false;
- listToReturn[0].add(new ShardDefaultMock());
+ shardListToReturn.add(new ShardDefaultMock());
ssi.applySaveOrUpdateOperation(op, null);
assertFalse(saveOrUpdateCalled[0]);
- assertTrue(updateCalled[0]);
+ assertFalse(mergeCalled[0]);
+ assertTrue(saveCalled[0]);
+
+ //TODO(maxr) write test for when we call merge()
}
public void testClose() {
18 years, 4 months
Hibernate SVN: r11458 - in trunk/HibernateExt/shards/src: test/org/hibernate/shards and 1 other directories.
by hibernate-commits@lists.jboss.org
Author: max.ross
Date: 2007-05-02 02:23:27 -0400 (Wed, 02 May 2007)
New Revision: 11458
Modified:
trunk/HibernateExt/shards/src/java/org/hibernate/shards/ShardedConfiguration.java
trunk/HibernateExt/shards/src/test/org/hibernate/shards/ShardedConfigurationTest.java
trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/BaseShardingIntegrationTestCase.java
Log:
simplify the way we establish our ShardedConfiguration
Modified: trunk/HibernateExt/shards/src/java/org/hibernate/shards/ShardedConfiguration.java
===================================================================
--- trunk/HibernateExt/shards/src/java/org/hibernate/shards/ShardedConfiguration.java 2007-05-02 06:18:10 UTC (rev 11457)
+++ trunk/HibernateExt/shards/src/java/org/hibernate/shards/ShardedConfiguration.java 2007-05-02 06:23:27 UTC (rev 11458)
@@ -18,24 +18,24 @@
package org.hibernate.shards;
-import org.hibernate.shards.cfg.ShardedEnvironment;
-import org.hibernate.shards.strategy.ShardStrategyFactory;
-import org.hibernate.shards.session.ShardedSessionFactoryImpl;
-import org.hibernate.shards.session.ShardedSessionFactory;
-import org.hibernate.shards.util.Preconditions;
-import org.hibernate.shards.util.Sets;
-import org.hibernate.shards.util.Maps;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.mapping.OneToOne;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
+import org.hibernate.shards.cfg.ShardConfiguration;
+import org.hibernate.shards.cfg.ShardedEnvironment;
+import org.hibernate.shards.session.ShardedSessionFactory;
+import org.hibernate.shards.session.ShardedSessionFactoryImpl;
+import org.hibernate.shards.strategy.ShardStrategyFactory;
+import org.hibernate.shards.util.Maps;
+import org.hibernate.shards.util.Preconditions;
+import org.hibernate.shards.util.Sets;
import org.hibernate.util.PropertiesHelper;
-import org.hibernate.SessionFactory;
import java.util.Collections;
import java.util.Iterator;
@@ -59,7 +59,7 @@
private final Configuration prototypeConfiguration;
// shard-specific configs
- private final List<Configuration> configurations;
+ private final List<ShardConfiguration> shardConfigs;
// user-defined sharding behavior
private final ShardStrategyFactory shardStrategyFactory;
@@ -73,80 +73,57 @@
// our lovely logger
private final Log log = LogFactory.getLog(getClass());
- // constant used in config files to specify the shard id
- static final String SHARD_ID_PROPERTY = "hibernate.connection.shard_id";
-
- // the properties that we let users vary across shards. if the property
- // isn't in this list we'll take the value from the prototype config
- static final Set<String> VARIABLE_PROPERTIES = Sets.newHashSet(
- Environment.URL,
- Environment.USER,
- Environment.PASS,
- Environment.SESSION_FACTORY_NAME,
- SHARD_ID_PROPERTY);
-
/**
* Constructs a ShardedConfiguration.
*
- * @param prototypeConfiguration The prototype for all configurations that
+ * @param prototypeConfiguration The prototype for all shardConfigs that
* will be used to create the {@link SessionFactory} objects
* that are internal to the {@link ShardedSessionFactory}.
- * Every {@link SessionFactory} within the
- * {@link ShardedSessionFactory} objects created by the ShardedConfiguration
- * will look the same, except for its values that correspond to
- * Configuration properties that we consider to be "variable" (they can
- * vary from shard to shard). These properties are:
- * {@link Environment#URL}
- * {@link Environment#USER}
- * {@link Environment#PASS}
- * {@link Environment#SESSION_FACTORY_NAME}
- * Unlike the {@link Configuration} instances contained in the configurations
- * param, this {@link Configuration} needs to have all of its mappings.
+ * Every {@link org.hibernate.SessionFactory} within the
+ * {@link org.hibernate.shards.session.ShardedSessionFactory} objects created by the ShardedConfiguration
+ * will look the same, except for properties that we consider to be "variable" (they can
+ * vary from shard to shard). The variable properties are defined by the
+ * {@link ShardedConfiguration} interface.
*
- * @param configurations The shard-specific {@link Configuration}s
+ * @param shardConfigs Shard-specific configuration data for each shard.
* @param shardStrategyFactory factory that knows how to create the right type of shard strategy
*/
public ShardedConfiguration(
Configuration prototypeConfiguration,
- List<Configuration> configurations,
+ List<ShardConfiguration> shardConfigs,
ShardStrategyFactory shardStrategyFactory) {
- this(prototypeConfiguration, configurations, shardStrategyFactory, Maps.<Integer, Integer>newHashMap());
+ this(prototypeConfiguration, shardConfigs, shardStrategyFactory, Maps.<Integer, Integer>newHashMap());
}
/**
* Constructs a ShardedConfiguration.
*
- * @param prototypeConfiguration The prototype for all configurations that
+ * @param prototypeConfiguration The prototype for all shardConfigs that
* will be used to create the {@link org.hibernate.SessionFactory} objects
* that are internal to the {@link org.hibernate.shards.session.ShardedSessionFactory}.
* Every {@link org.hibernate.SessionFactory} within the
* {@link org.hibernate.shards.session.ShardedSessionFactory} objects created by the ShardedConfiguration
- * will look the same, except for its values that correspond to
- * Configuration properties that we consider to be "variable" (they can
- * vary from shard to shard). These properties are:
- * {@link org.hibernate.cfg.Environment#URL}
- * {@link org.hibernate.cfg.Environment#USER}
- * {@link org.hibernate.cfg.Environment#PASS}
- * {@link org.hibernate.cfg.Environment#SESSION_FACTORY_NAME}
- * Unlike the {@link org.hibernate.cfg.Configuration} instances contained in the configurations
- * param, this {@link org.hibernate.cfg.Configuration} needs to have all of its mappings.
- *@param configurations Cannot be empty.
+ * will look the same, except for properties that we consider to be "variable" (they can
+ * vary from shard to shard). The variable properties are defined by the
+ * {@link ShardedConfiguration} interface.
+ *
+ * @param shardConfigs Shard-specific configuration data for each shard.
* @param shardStrategyFactory factory that knows how to create the right kind of shard strategy
* @param virtualShardToShardMap A map that maps virtual shard ids to real
*/
public ShardedConfiguration(
Configuration prototypeConfiguration,
- List<Configuration> configurations,
+ List<ShardConfiguration> shardConfigs,
ShardStrategyFactory shardStrategyFactory,
Map<Integer, Integer> virtualShardToShardMap) {
Preconditions.checkNotNull(prototypeConfiguration);
- Preconditions.checkNotNull(configurations);
- Preconditions.checkArgument(!configurations.isEmpty());
+ Preconditions.checkNotNull(shardConfigs);
+ Preconditions.checkArgument(!shardConfigs.isEmpty());
Preconditions.checkNotNull(shardStrategyFactory);
Preconditions.checkNotNull(virtualShardToShardMap);
this.prototypeConfiguration = prototypeConfiguration;
- this.configurations = configurations;
+ this.shardConfigs = shardConfigs;
this.shardStrategyFactory = shardStrategyFactory;
this.virtualShardToShardMap = virtualShardToShardMap;
if (!virtualShardToShardMap.isEmpty()) {
@@ -178,10 +155,16 @@
// we can get the set from the prototype and then just reuse it.
Set<Class<?>> classesWithoutTopLevelSaveSupport =
determineClassesWithoutTopLevelSaveSupport(prototypeConfiguration);
- for (Configuration config : configurations) {
+ for (ShardConfiguration config : shardConfigs) {
populatePrototypeWithVariableProperties(config);
// get the shardId from the shard-specific config
- Integer shardId = Integer.parseInt(config.getProperty(SHARD_ID_PROPERTY));
+ Integer shardId = config.getShardId();
+ if(shardId == null) {
+ final String msg = "Attempt to build a ShardedSessionFactory using a "
+ + "ShardConfiguration that has a null shard id.";
+ log.fatal(msg);
+ throw new NullPointerException(msg);
+ }
Set<ShardId> virtualShardIds;
if (virtualShardToShardMap.isEmpty()) {
// simple case, virtual and physical are the same
@@ -241,29 +224,15 @@
* a shard-specific config and sets them as the values of the same properties
* in the prototype config.
*/
- void populatePrototypeWithVariableProperties(Configuration config) {
- copyVariableProperties(prototypeConfiguration, config);
+ void populatePrototypeWithVariableProperties(ShardConfiguration config) {
+ prototypeConfiguration.setProperty(Environment.USER, config.getShardUser());
+ prototypeConfiguration.setProperty(Environment.PASS, config.getShardPassword());
+ prototypeConfiguration.setProperty(Environment.URL, config.getShardUrl());
+ prototypeConfiguration.setProperty(Environment.SESSION_FACTORY_NAME, config.getShardSessionFactoryName());
+ prototypeConfiguration.setProperty(ShardedEnvironment.SHARD_ID_PROPERTY, config.getShardId().toString());
}
/**
- * Helper function to copy variable properties from the shard-specific config
- * to the prototype config
- */
- static void copyVariableProperties(Configuration prototype, Configuration config) {
- for(String property : VARIABLE_PROPERTIES) {
- copyPropertyToPrototype(prototype, config, property);
- }
- }
-
- /**
- * Helper function to copy one variable property from the shard-specific config
- * to the prototype config
- */
- static void copyPropertyToPrototype(Configuration prototype, Configuration config, String property) {
- prototype.setProperty(property, config.getProperty(property));
- }
-
- /**
* Helper function that creates an actual SessionFactory.
*/
private SessionFactoryImplementor buildSessionFactory() {
Modified: trunk/HibernateExt/shards/src/test/org/hibernate/shards/ShardedConfigurationTest.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/ShardedConfigurationTest.java 2007-05-02 06:18:10 UTC (rev 11457)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/ShardedConfigurationTest.java 2007-05-02 06:23:27 UTC (rev 11458)
@@ -18,13 +18,9 @@
package org.hibernate.shards;
-import org.hibernate.shards.strategy.ShardStrategy;
-import org.hibernate.shards.strategy.ShardStrategyFactoryDefaultMock;
-import org.hibernate.shards.session.ShardedSessionFactoryImpl;
-import org.hibernate.shards.util.Lists;
-
import junit.framework.TestCase;
+import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.HSQLDialect;
@@ -33,6 +29,11 @@
import org.hibernate.mapping.Property;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.Table;
+import org.hibernate.shards.cfg.ShardConfiguration;
+import org.hibernate.shards.session.ShardedSessionFactoryImpl;
+import org.hibernate.shards.strategy.ShardStrategy;
+import org.hibernate.shards.strategy.ShardStrategyFactoryDefaultMock;
+import org.hibernate.shards.util.Lists;
import java.util.Collections;
import java.util.List;
@@ -43,7 +44,7 @@
public class ShardedConfigurationTest extends TestCase {
private MyShardStrategyFactory shardStrategyFactory;
- private Configuration config;
+ private ShardConfiguration shardConfig;
private ShardedConfiguration shardedConfiguration;
@Override
@@ -51,23 +52,21 @@
super.setUp();
shardStrategyFactory = new MyShardStrategyFactory();
- config = new Configuration();
- for(String prop : ShardedConfiguration.VARIABLE_PROPERTIES) {
- config.setProperty(prop, "33");
- }
- config.setProperty(Environment.DIALECT, HSQLDialect.class.getName());
+ Configuration protoConfig = new Configuration();
+ protoConfig.setProperty(Environment.DIALECT, HSQLDialect.class.getName());
+ shardConfig = new MyShardConfig("user", "url", "pwd", "sfname", 33);
shardedConfiguration =
new ShardedConfiguration(
- config,
- Collections.singletonList(config),
+ protoConfig,
+ Collections.singletonList(shardConfig),
shardStrategyFactory);
}
public void testBuildShardedSessionFactoryPreconditions() throws Exception {
- List<Configuration> configList = Lists.newArrayList(config);
+ List<ShardConfiguration> shardConfigs = Lists.newArrayList(shardConfig);
try {
- new ShardedConfiguration(null, configList, shardStrategyFactory);
+ new ShardedConfiguration(null, shardConfigs, shardStrategyFactory);
fail("Expected npe");
} catch (NullPointerException npe) {
// good
@@ -81,9 +80,9 @@
// good
}
- configList.clear();
+ shardConfigs.clear();
try {
- new ShardedConfiguration(config, configList, shardStrategyFactory);
+ new ShardedConfiguration(config, shardConfigs, shardStrategyFactory);
fail("Expected iae");
} catch (IllegalArgumentException iae) {
// good
@@ -91,7 +90,7 @@
}
public void testShardIdRequired() {
- Configuration config = new Configuration();
+ ShardConfiguration config = new MyShardConfig("user", "url", "pwd", "sfname", null);
try {
shardedConfiguration.populatePrototypeWithVariableProperties(config);
fail("expected npe");
@@ -100,17 +99,13 @@
}
}
- public void testCopyPropertyToPrototype() {
- Configuration prototype = new Configuration();
- String copyMe = "copyMe";
- config.setProperty(copyMe, "yamma");
- ShardedConfiguration.copyPropertyToPrototype(prototype, config, copyMe);
- assertEquals(config.getProperty(copyMe), prototype.getProperty(copyMe));
- }
-
public void testBuildShardedSessionFactory() {
ShardedSessionFactoryImpl ssfi = (ShardedSessionFactoryImpl)shardedConfiguration.buildShardedSessionFactory();
assertNotNull(ssfi);
+ // make sure the session factory contained in the sharded session factory
+ // has the number of session factories we expect
+ List<SessionFactory> sfList = ssfi.getSessionFactories();
+ assertEquals(1, sfList.size());
}
public void testRequiresShardLock() {
@@ -130,4 +125,42 @@
return null;
}
}
+
+ private static final class MyShardConfig implements ShardConfiguration {
+
+ private final String user;
+ private final String url;
+ private final String password;
+ private final String sessionFactoryName;
+ private final Integer shardId;
+
+ public MyShardConfig(String user, String url, String password,
+ String sessionFactoryName, Integer shardId) {
+ this.user = user;
+ this.url = url;
+ this.password = password;
+ this.sessionFactoryName = sessionFactoryName;
+ this.shardId = shardId;
+ }
+
+ public String getShardUser() {
+ return user;
+ }
+
+ public String getShardUrl() {
+ return url;
+ }
+
+ public String getShardPassword() {
+ return password;
+ }
+
+ public String getShardSessionFactoryName() {
+ return sessionFactoryName;
+ }
+
+ public Integer getShardId() {
+ return shardId;
+ }
+ }
}
Modified: trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/BaseShardingIntegrationTestCase.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/BaseShardingIntegrationTestCase.java 2007-05-02 06:18:10 UTC (rev 11457)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/BaseShardingIntegrationTestCase.java 2007-05-02 06:23:27 UTC (rev 11458)
@@ -18,17 +18,23 @@
package org.hibernate.shards.integration;
+import junit.framework.TestCase;
+
+import org.hibernate.Session;
+import org.hibernate.cfg.Configuration;
import org.hibernate.shards.ShardId;
import org.hibernate.shards.ShardedConfiguration;
-import org.hibernate.shards.session.ShardedSessionFactory;
+import org.hibernate.shards.cfg.ConfigurationToShardConfigurationAdapter;
+import org.hibernate.shards.cfg.ShardConfiguration;
import org.hibernate.shards.integration.platform.DatabasePlatform;
import org.hibernate.shards.integration.platform.DatabasePlatformFactory;
import org.hibernate.shards.loadbalance.RoundRobinShardLoadBalancer;
+import org.hibernate.shards.session.ShardedSession;
+import org.hibernate.shards.session.ShardedSessionFactory;
import org.hibernate.shards.session.ShardedSessionImpl;
-import org.hibernate.shards.session.ShardedSession;
import org.hibernate.shards.strategy.ShardStrategy;
+import org.hibernate.shards.strategy.ShardStrategyFactory;
import org.hibernate.shards.strategy.ShardStrategyImpl;
-import org.hibernate.shards.strategy.ShardStrategyFactory;
import org.hibernate.shards.strategy.access.ParallelShardAccessStrategy;
import org.hibernate.shards.strategy.access.SequentialShardAccessStrategy;
import org.hibernate.shards.strategy.access.ShardAccessStrategy;
@@ -40,12 +46,6 @@
import org.hibernate.shards.util.Lists;
import org.hibernate.shards.util.Maps;
-import junit.framework.AssertionFailedError;
-import junit.framework.TestCase;
-
-import org.hibernate.Session;
-import org.hibernate.cfg.Configuration;
-
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -102,7 +102,8 @@
destroyDatabase(i);
createDatabase(i);
}
- List<Configuration> configurations = buildConfigurations();
+ Configuration prototypeConfig = buildPrototypeConfig();
+ List<ShardConfiguration> configurations = buildConfigurations();
// now we use these configs to build our sharded config
ShardStrategyFactory shardStrategyFactory = buildShardStrategyFactory();
Map<Integer, Integer> virtualShardMap = buildVirtualShardToShardMap();
@@ -110,7 +111,7 @@
// that all other configs will be the same
ShardedConfiguration shardedConfig =
new ShardedConfiguration(
- configurations.get(0),
+ prototypeConfig,
configurations,
shardStrategyFactory,
virtualShardMap);
@@ -132,16 +133,24 @@
return virtualShardToShardMap;
}
- protected List<Configuration> buildConfigurations() {
+ private Configuration buildPrototypeConfig() {
DatabasePlatform dbPlatform = DatabasePlatformFactory.FACTORY.getDatabasePlatform();
String dbPlatformConfigDirectory = "platform/" + dbPlatform.getName().toLowerCase() +"/config/";
IdGenType idGenType = getIdGenType();
- List<Configuration> configs = Lists.newArrayList();
+ Configuration config = new Configuration();
+ config.configure(BaseShardingIntegrationTestCase.class.getResource(dbPlatformConfigDirectory + "shard0.hibernate.cfg.xml"));
+ config.addURL(BaseShardingIntegrationTestCase.class.getResource(dbPlatformConfigDirectory + idGenType.getMappingFile()));
+ return config;
+ }
+
+ protected List<ShardConfiguration> buildConfigurations() {
+ DatabasePlatform dbPlatform = DatabasePlatformFactory.FACTORY.getDatabasePlatform();
+ String dbPlatformConfigDirectory = "platform/" + dbPlatform.getName().toLowerCase() +"/config/";
+ List<ShardConfiguration> configs = Lists.newArrayList();
for(int i = 0; i < getNumDatabases(); i++) {
Configuration config = new Configuration();
config.configure(BaseShardingIntegrationTestCase.class.getResource(dbPlatformConfigDirectory + "shard" + i + ".hibernate.cfg.xml"));
- config.addURL(BaseShardingIntegrationTestCase.class.getResource(dbPlatformConfigDirectory + idGenType.getMappingFile()));
- configs.add(config);
+ configs.add(new ConfigurationToShardConfigurationAdapter(config));
}
return configs;
}
@@ -158,6 +167,12 @@
};
}
+ protected void commitAndResetSession() {
+ session.getTransaction().commit();
+ resetSession();
+ session.beginTransaction();
+ }
+
protected void resetSession() {
MemoryLeakPlugger.plug((ShardedSessionImpl)session);
session.close();
@@ -334,26 +349,11 @@
public void runBare() throws Throwable {
try {
super.runBare();
- } catch (AssertionFailedError afe) {
- AssertionFailedError newError = new AssertionFailedError(perm.getMessageWithPermutationPrefix(afe.getMessage()));
- newError.setStackTrace(afe.getStackTrace());
- throw newError;
} catch (Throwable t) {
- throw new ThrowableDecorator(t);
+ throw new RuntimeException(perm.getMessageWithPermutationPrefix(t.getMessage()), t);
+ // TODO(maxr) handel assertion failure separately so they get properly reported
}
}
-
- private final class ThrowableDecorator extends Throwable {
-
- public ThrowableDecorator(Throwable t) {
- super(t);
- }
-
- @Override
- public String getMessage() {
- return perm.getMessageWithPermutationPrefix(getCause().getMessage());
- }
- }
}
18 years, 4 months
Hibernate SVN: r11457 - trunk/HibernateExt/shards/src/test/org/hibernate/shards.
by hibernate-commits@lists.jboss.org
Author: max.ross
Date: 2007-05-02 02:18:10 -0400 (Wed, 02 May 2007)
New Revision: 11457
Modified:
trunk/HibernateExt/shards/src/test/org/hibernate/shards/ShardDefaultMock.java
Log:
adding merge() to Shard interface
Modified: trunk/HibernateExt/shards/src/test/org/hibernate/shards/ShardDefaultMock.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/ShardDefaultMock.java 2007-05-02 06:17:34 UTC (rev 11456)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/ShardDefaultMock.java 2007-05-02 06:18:10 UTC (rev 11457)
@@ -18,6 +18,11 @@
package org.hibernate.shards;
+import org.hibernate.Criteria;
+import org.hibernate.LockMode;
+import org.hibernate.Query;
+import org.hibernate.classic.Session;
+import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.shards.criteria.CriteriaEvent;
import org.hibernate.shards.criteria.CriteriaId;
import org.hibernate.shards.criteria.ShardedCriteria;
@@ -26,12 +31,6 @@
import org.hibernate.shards.query.ShardedQuery;
import org.hibernate.shards.session.OpenSessionEvent;
-import org.hibernate.Criteria;
-import org.hibernate.LockMode;
-import org.hibernate.Query;
-import org.hibernate.classic.Session;
-import org.hibernate.engine.SessionFactoryImplementor;
-
import java.io.Serializable;
import java.util.List;
import java.util.Set;
@@ -148,4 +147,12 @@
public Object uniqueResult(QueryId queryId) {
throw new UnsupportedOperationException();
}
+
+ public void merge(Object object) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void merge(String entityName, Object object) {
+ throw new UnsupportedOperationException();
+ }
}
18 years, 4 months
Hibernate SVN: r11456 - trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/platform/hsql.
by hibernate-commits@lists.jboss.org
Author: max.ross
Date: 2007-05-02 02:17:34 -0400 (Wed, 02 May 2007)
New Revision: 11456
Modified:
trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/platform/hsql/HSQLDatabasePlatform.java
Log:
adds table for IdIsBaseType
Modified: trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/platform/hsql/HSQLDatabasePlatform.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/platform/hsql/HSQLDatabasePlatform.java 2007-05-02 06:16:34 UTC (rev 11455)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/platform/hsql/HSQLDatabasePlatform.java 2007-05-02 06:17:34 UTC (rev 11456)
@@ -54,6 +54,7 @@
,"CREATE TABLE FloorElevator (floorId DECIMAL(40,0), elevatorId DECIMAL(40,0), PRIMARY KEY(floorId, elevatorId))"
,"CREATE TABLE Escalator (escalatorId DECIMAL(40,0) PRIMARY KEY, bottomFloorId DECIMAL(40,0), topFloorId DECIMAL(40,0))"
,"CREATE TABLE Person (personId DECIMAL(40,0) PRIMARY KEY, name VARCHAR(50), tenantId DECIMAL(40,0), officeId DECIMAL(40,0))"
+ ,"CREATE TABLE IdIsBaseType (idIsBaseTypeId DECIMAL(40,0) PRIMARY KEY, value VARCHAR(50))"
);
protected static final List<String> DROP_TABLE_STATEMENTS = Lists.newArrayList(
18 years, 4 months
Hibernate SVN: r11455 - trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg.
by hibernate-commits@lists.jboss.org
Author: max.ross
Date: 2007-05-02 02:16:34 -0400 (Wed, 02 May 2007)
New Revision: 11455
Modified:
trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ShardedEnvironment.java
Log:
add a constant for the shard id property (part of config rework)
Modified: trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ShardedEnvironment.java
===================================================================
--- trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ShardedEnvironment.java 2007-05-02 06:15:39 UTC (rev 11454)
+++ trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ShardedEnvironment.java 2007-05-02 06:16:34 UTC (rev 11455)
@@ -38,5 +38,10 @@
*/
public static final String CHECK_ALL_ASSOCIATED_OBJECTS_FOR_DIFFERENT_SHARDS = "hibernate.shard.enable_cross_shard_relationship_checks";
+ /**
+ * Unique identifier for a shard. Must be an Integer.
+ */
+ public static final String SHARD_ID_PROPERTY = "hibernate.connection.shard_id";
+
private ShardedEnvironment() {}
}
18 years, 4 months
Hibernate SVN: r11454 - trunk/HibernateExt/shards/src/test/org/hibernate/shards/model.
by hibernate-commits@lists.jboss.org
Author: max.ross
Date: 2007-05-02 02:15:39 -0400 (Wed, 02 May 2007)
New Revision: 11454
Modified:
trunk/HibernateExt/shards/src/test/org/hibernate/shards/model/Building.java
Log:
expose setBuildingId
Modified: trunk/HibernateExt/shards/src/test/org/hibernate/shards/model/Building.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/model/Building.java 2007-05-02 06:14:00 UTC (rev 11453)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/model/Building.java 2007-05-02 06:15:39 UTC (rev 11454)
@@ -20,8 +20,8 @@
import org.hibernate.shards.util.Lists;
+import java.io.Serializable;
import java.util.List;
-import java.io.Serializable;
/**
* @author Max Ross <maxr(a)google.com>
@@ -38,7 +38,7 @@
return buildingId;
}
- void setBuildingId(Serializable buildingId) {
+ public void setBuildingId(Serializable buildingId) {
this.buildingId = buildingId;
}
18 years, 4 months
Hibernate SVN: r11453 - trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/platform/hsql/config.
by hibernate-commits@lists.jboss.org
Author: max.ross
Date: 2007-05-02 02:14:00 -0400 (Wed, 02 May 2007)
New Revision: 11453
Modified:
trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/platform/hsql/config/mappings.hbm.xml
Log:
mapping for IdIsBaseType
Modified: trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/platform/hsql/config/mappings.hbm.xml
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/platform/hsql/config/mappings.hbm.xml 2007-05-02 06:09:56 UTC (rev 11452)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/integration/platform/hsql/config/mappings.hbm.xml 2007-05-02 06:14:00 UTC (rev 11453)
@@ -121,6 +121,13 @@
</bag>
</class>
+ <class name="IdIsBaseType" table="IdIsBaseType">
+ <id name="idIsBaseTypeId" type="long">
+ <generator class="org.hibernate.shards.id.ShardedTableHiLoGenerator"/>
+ </id>
+ <property name="value" not-null="true"/>
+ </class>
+
<query name="SelectFloorsHigherThan">
<![CDATA[from Floor as f where f.number >= :lowestFloor]]>
</query>
18 years, 4 months
Hibernate SVN: r11452 - trunk/HibernateExt/shards/src/test/org/hibernate/shards/model.
by hibernate-commits@lists.jboss.org
Author: max.ross
Date: 2007-05-02 02:09:56 -0400 (Wed, 02 May 2007)
New Revision: 11452
Added:
trunk/HibernateExt/shards/src/test/org/hibernate/shards/model/IdIsBaseType.java
Log:
add helper class for test that verifies we can support objects with ids that are base types
Added: trunk/HibernateExt/shards/src/test/org/hibernate/shards/model/IdIsBaseType.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/model/IdIsBaseType.java (rev 0)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/model/IdIsBaseType.java 2007-05-02 06:09:56 UTC (rev 11452)
@@ -0,0 +1,45 @@
+/**
+ * Copyright (C) 2007 Google Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+package org.hibernate.shards.model;
+
+/**
+ * Test class used for tests that illustrate we can handle objects with
+ * ids that are base types.
+ *
+ * @author maxr(a)google.com (Max Ross)
+ */
+public class IdIsBaseType {
+ private long idIsBaseTypeId;
+ private String value;
+
+ public long getIdIsBaseTypeId() {
+ return idIsBaseTypeId;
+ }
+
+ public void setIdIsBaseTypeId(long hasLongId) {
+ this.idIsBaseTypeId = hasLongId;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+}
18 years, 4 months
Hibernate SVN: r11451 - trunk/HibernateExt/shards/src/test/org/hibernate/shards/defaultmock.
by hibernate-commits@lists.jboss.org
Author: max.ross
Date: 2007-05-02 02:07:43 -0400 (Wed, 02 May 2007)
New Revision: 11451
Added:
trunk/HibernateExt/shards/src/test/org/hibernate/shards/defaultmock/ShardConfigurationDefaultMock.java
Log:
default mock impl of the ShardConfiguration interface.
Added: trunk/HibernateExt/shards/src/test/org/hibernate/shards/defaultmock/ShardConfigurationDefaultMock.java
===================================================================
--- trunk/HibernateExt/shards/src/test/org/hibernate/shards/defaultmock/ShardConfigurationDefaultMock.java (rev 0)
+++ trunk/HibernateExt/shards/src/test/org/hibernate/shards/defaultmock/ShardConfigurationDefaultMock.java 2007-05-02 06:07:43 UTC (rev 11451)
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2007 Google Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+package org.hibernate.shards.defaultmock;
+
+import org.hibernate.shards.cfg.ShardConfiguration;
+
+/**
+ * @author maxr(a)google.com (Max Ross)
+ */
+public class ShardConfigurationDefaultMock implements ShardConfiguration {
+
+ public String getShardUrl() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getShardUser() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getShardPassword() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getShardSessionFactoryName() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Integer getShardId() {
+ throw new UnsupportedOperationException();
+ }
+}
+
18 years, 4 months
Hibernate SVN: r11450 - trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg.
by hibernate-commits@lists.jboss.org
Author: max.ross
Date: 2007-05-02 02:07:08 -0400 (Wed, 02 May 2007)
New Revision: 11450
Added:
trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ConfigurationToShardConfigurationAdapter.java
trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ShardConfiguration.java
Log:
Add the ShardConfiguration interface and an impl that adapts the standard Configuration to this interface.
Added: trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ConfigurationToShardConfigurationAdapter.java
===================================================================
--- trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ConfigurationToShardConfigurationAdapter.java (rev 0)
+++ trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ConfigurationToShardConfigurationAdapter.java 2007-05-02 06:07:08 UTC (rev 11450)
@@ -0,0 +1,55 @@
+/**
+ * Copyright (C) 2007 Google Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+package org.hibernate.shards.cfg;
+
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+
+/**
+ * Adapt a {@link Configuration} to the {@link ShardConfiguration} interface.
+ *
+ * @author maxr(a)google.com (Max Ross)
+ */
+public class ConfigurationToShardConfigurationAdapter implements ShardConfiguration {
+
+ private final Configuration config;
+
+ public ConfigurationToShardConfigurationAdapter(Configuration config) {
+ this.config = config;
+ }
+
+ public String getShardUrl() {
+ return config.getProperty(Environment.URL);
+ }
+
+ public String getShardUser() {
+ return config.getProperty(Environment.USER);
+ }
+
+ public String getShardPassword() {
+ return config.getProperty(Environment.PASS);
+ }
+
+ public String getShardSessionFactoryName() {
+ return config.getProperty(Environment.SESSION_FACTORY_NAME);
+ }
+
+ public Integer getShardId() {
+ return Integer.parseInt(config.getProperty(ShardedEnvironment.SHARD_ID_PROPERTY));
+ }
+}
Added: trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ShardConfiguration.java
===================================================================
--- trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ShardConfiguration.java (rev 0)
+++ trunk/HibernateExt/shards/src/java/org/hibernate/shards/cfg/ShardConfiguration.java 2007-05-02 06:07:08 UTC (rev 11450)
@@ -0,0 +1,53 @@
+/**
+ * Copyright (C) 2007 Google Inc.
+ *
+ * This library is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation; either version 2.1 of the License, or (at your option)
+ * any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+package org.hibernate.shards.cfg;
+
+/**
+ * Describes the configuration properties that can vary across the {@link org.hibernate.SessionFactory}
+ * instances contained within your {@link org.hibernate.shards.session.ShardedSessionFactory}.
+ *
+ * @author maxr(a)google.com (Max Ross)
+ */
+public interface ShardConfiguration {
+
+ /**
+ * @return the url of the shard
+ */
+ String getShardUrl();
+
+ /**
+ * @return the user that will be sent to the shard for authentication
+ */
+ String getShardUser();
+
+ /**
+ * @return the password that will be sent to the shard for authentication
+ */
+ String getShardPassword();
+
+ /**
+ * @return the name that the {@link org.hibernate.SessionFactory} created from
+ * this config will have
+ */
+ String getShardSessionFactoryName();
+
+ /**
+ * @return unique id of the shard
+ */
+ Integer getShardId();
+}
18 years, 4 months