-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: clearing the whole database ?
PostPosted: Sat Jul 07, 2007 9:22 am 
Newbie

Joined: Sun Aug 20, 2006 8:09 pm
Posts: 8
Hi !
I'm searching for a decent method to remove all objects from the database. I want to do this before running my test-code to be sure the database is in a known state.
I tried to query for my base class and then ISession.Delete the objects sequentially. But the db I use (PostgreSQL) has foreign key constraints ( great thing, but not in this case) which prevent referenced objects to be deleted.

Sure, I could drop all db tables and recreate them every time. But maybe there is a better way via NHibernates interface to clear the db.

Thanks for help
Thomas


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jul 07, 2007 4:57 pm 
Newbie

Joined: Tue Jul 03, 2007 2:06 pm
Posts: 14
Location: Turkey, Ankara
best method should be disabling the contraints in the database and then delete all the objects with a recursive sql ant task i think. All some coding may do the same work but i do not know if it is possible in postgresql.
Hence deleting large number of objects may be costly for hibernate.

_________________
it is what they understand from your sayings, not what u know.

Fatih Kucukpetek


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 11, 2007 11:51 am 
Expert
Expert

Joined: Fri May 13, 2005 11:13 am
Posts: 292
Location: Rochester, NY
In a testing scenario, I think the best option is to use hbm2ddl to recreate the database before starting. That isn't always an option if you're starting from an existing schema, though.

Here's a really hacky solution that doesn't us NH per se, but does expoit the mapping metadata to get at information about an implied table clearing ordering:

Code:
   /// <summary>A dependency chain for deleting objects.</summary>
   /// <remarks>Records which loaded objects are dependent on each other so the tables can
   /// be automatically cleaned out at the end of a test fixture.  These aren't explicit
   /// dependencies, really, just a failsafe table clearing order that won't interfere with
   /// database DRI.
   /// <para>
   /// Detects dependencies within an <see cref="NHibernate.Cfg.Configuration"/>.
   /// </remarks>
   public class DeletionChain {
      private static log4net.ILog log = log4net.LogManager.GetLogger( System.Reflection.MethodBase.GetCurrentMethod().DeclaringType );

      private NHibernate.Cfg.Configuration cfg;
      private IList mainClassChain;
      private IList leafTableChain;
//      private IList chainedClasses;

      #region ctor

      public DeletionChain(NHibernate.Cfg.Configuration configuration) {
         cfg = configuration;
         mainClassChain= new ArrayList();
         leafTableChain = new ArrayList();
//         chainedClasses = new ArrayList();
         BuildChain();
      }

      #endregion

      #region Build

      private void BuildChain() {
         log.Info("Building table dependency chain");

         foreach (PersistentClass pc in cfg.ClassMappings)
            this.AddClass( pc );
      }

      private int level = 0;

      private void AddClass(PersistentClass pc) {
         level++;
         string levelSpace = string.Empty.PadRight( level );

         if (pc.IsMutable && (pc is RootClass) && !mainClassChain.Contains(pc)) {
            log.DebugFormat( "{0}Inspecting {1}", levelSpace, pc.Name );
            foreach(Property prop in pc.SubclassPropertyClosureCollection) {
               if ((prop.Value is Collection) && !leafTableChain.Contains( ((Collection)prop.Value).CollectionTable )
                  && !((Collection)prop.Value).IsInverse
                  ) {
                  log.DebugFormat( "{0}Adding collection table {1}", levelSpace, ((Collection)prop.Value).CollectionTable.Name);
                  leafTableChain.Add( ((Collection)prop.Value).CollectionTable );
               }

               if ( (prop.Value is ToOne) && prop.IsInsertable )   // HACK: there still could be a dependency, but for now...
                  AddClass( cfg.GetClassMapping( prop.Value.Type.ReturnedClass ).RootClazz );
            }

            log.DebugFormat( "{0}Adding {1}", levelSpace, pc.Name);
            mainClassChain.Add(pc);
         }
         else if (log.IsDebugEnabled) {
            string reason = null;
            if (!pc.IsMutable) reason = "immutable";
            else if (pc is Subclass) reason = "subclass";
            else if ( mainClassChain.Contains( pc ) ) reason = "already chained";
            else reason = "unknown!";

            log.DebugFormat( "{2}...skipping {0} ({1})", pc.Name, reason, levelSpace );
         }

         level--;
      }

      #endregion

      #region Pop & Peek

      /// <summary>Gets the next "leaf" table and "pops" it off the chain.</summary>
      /// <returns>A NHibernate <see cref="NHibernate.Mapping.Table"/>.</returns>
      public Table Pop() { return popPeek( true ); }

      /// <summary>Gets the next "leaf" table and leaves in on the chain.</summary>
      /// <returns>A NHibernate <see cref="NHibernate.Mapping.Table"/>.</returns>
      public Table Peek() { return popPeek( false ); }

      private Table popPeek(bool pop) {
         Table link = null;
         int leafCount = leafTableChain.Count;
         int mainCount = mainClassChain.Count;

         if (leafCount > 0) {
            link = (Table)leafTableChain[ leafCount - 1 ];
            if (pop) leafTableChain.RemoveAt( leafCount - 1 );
         }
         else if (mainCount > 0) {
            link = ((PersistentClass)mainClassChain[ mainCount - 1 ]).Table;
            if (pop) mainClassChain.RemoveAt( mainCount - 1 );
         }
         
         return link;
      }

      #endregion
   }


To use, just construct and call Build(). Then, after you're done testing (or before you start) Pop() each table off the chain, and send a
Code:
"delete " + table.Name
to the db.

caveat emptor. This remains untested outside my own use. Modifications may be necessary to make it usable for you.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.