嘗試了其他工具,並有問題。這是我的家庭解決方案。可能需要一些清理,但它的肉在那裏。
import java.io.Serializable;
import java.util.List;
import java.util.logging.Logger;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.hibernate.Session;
import org.hibernate.Transaction;
import ca.digitalrapids.lang.GeneralException;
import ca.digitalrapids.mediamanager.server.dao.hibernate.GenericDAOHibernate;
import ca.digitalrapids.mediamanager.server.dao.hibernate.GenericDAOHibernate.GenericDAOHibernateFactory;
import ca.digitalrapids.persist.dao.DAOOptions;
import ca.digitalrapids.persist.hibernate.HibernateUtil2;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
@RequiredArgsConstructor
public class DataMigrator
{
private static final Logger logger = Logger
.getLogger(DataMigrator.class.getName());
private final HibernateUtil2 sourceHibernateUtil2;
private final HibernateUtil2 destHibernateUtil2;
private final ImmutableSet<Class<?>> beanClassesToMigrate;
@Setter @Getter
private Integer copyBatchSize = 10;
@Setter
private GenericDAOHibernateFactory sourceDaoFactory =
new GenericDAOHibernate.GenericDAOHibernateFactoryImpl();
@Setter
private GenericDAOHibernateFactory destDaoFactory =
new GenericDAOHibernate.GenericDAOHibernateFactoryImpl();
private final ImmutableMultimap<Class<?>, Class<?>> entityDependencies;
public void run() throws GeneralException
{
migrateData(sourceHibernateUtil2.getSession(),
destHibernateUtil2.getSession());
}
private void migrateData(Session sourceSession, Session destSession)
throws GeneralException
{
logger.info("\nMigrating data from old HSQLDB database.\n");
Transaction destTransaction = null;
try
{
destTransaction = destSession.beginTransaction();
migrateBeans(sourceSession, destSession, beanClassesToMigrate,
entityDependencies);
destTransaction.commit();
} catch (Throwable e) {
if (destTransaction != null)
destTransaction.rollback();
throw e;
}
logger.info("\nData migration complete!\n");
}
private void migrateBeans(Session sourceSession, Session destSession,
ImmutableSet<Class<?>> beanClasses, ImmutableMultimap<Class<?>, Class<?>> deps)
{
if (beanClasses.isEmpty()) return;
Class<?> head = beanClasses.iterator().next();
ImmutableSet<Class<?>> tail =
Sets.difference(beanClasses, ImmutableSet.of(head)).immutableCopy();
ImmutableSet<Class<?>> childrenOfHead = getChildren(head, tail, deps);
migrateBeans(sourceSession, destSession, childrenOfHead, deps);
migrateBean(sourceSession, destSession, head);
migrateBeans(sourceSession, destSession,
Sets.difference(tail, childrenOfHead).immutableCopy(), deps);
}
private ImmutableSet<Class<?>> getChildren(Class<?> parent,
ImmutableSet<Class<?>> possibleChildren,
ImmutableMultimap<Class<?>, Class<?>> deps)
{
ImmutableSet<Class<?>> parentDeps = ImmutableSet.copyOf(deps.get(parent));
return Sets.intersection(possibleChildren, parentDeps).immutableCopy();
}
private void migrateBean(Session sourceSession, Session destSession,
Class<?> beanClass)
{
GenericDAOHibernate<?, Serializable> sourceDao =
sourceDaoFactory.get(beanClass, sourceSession);
logger.info("Migrating "+sourceDao.countAll()+" of "+beanClass);
DAOOptions options = new DAOOptions();
options.setMaxResults(copyBatchSize);
List<?> sourceBeans;
int firstResult = 0;
int sourceBeansSize;
do {
options.setFirstResult(firstResult);
sourceBeans = sourceDao.findAll(options);
sourceBeansSize = sourceBeans.size();
@SuppressWarnings("unchecked")
GenericDAOHibernate<Object, Serializable> destDao =
(GenericDAOHibernate<Object, Serializable>)
destDaoFactory.get(beanClass, destSession);
for (Object sourceBean : sourceBeans)
{
destDao.save(sourceBean);
}
firstResult += copyBatchSize;
sourceSession.clear();/* prevent memory problems */
} while (sourceBeansSize >= copyBatchSize);
}
}
我正在嘗試這個,但遇到了循環關係的問題。調查禁用dest DB約束,但找不到一個明顯的方法來做到這一點。可能必須編寫自定義代碼來刪除/重建違規關係。 – 2012-09-27 15:55:31