Point checkin. Hibernate is currently beating me up by not doing

what I expect when trying to determine the concrete type of a polymorphic
type.  Some major surgery seems to be in order.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/BRANCHES/WCM-DEV2/root@2927 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Britt Park
2006-05-20 15:34:17 +00:00
parent 72751fdedb
commit 2ee957f5e2
7 changed files with 164 additions and 70 deletions

View File

@@ -17,6 +17,8 @@
package org.alfresco.repo.avm; package org.alfresco.repo.avm;
import java.util.ArrayList;
import org.alfresco.repo.avm.hibernate.HibernateHelper; import org.alfresco.repo.avm.hibernate.HibernateHelper;
import org.alfresco.repo.avm.impl.AVMServiceImpl; import org.alfresco.repo.avm.impl.AVMServiceImpl;
import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Configuration;
@@ -56,6 +58,7 @@ public class AVMServiceTest extends TestCase
@Override @Override
protected void tearDown() throws Exception protected void tearDown() throws Exception
{ {
HibernateHelper.Reset();
} }
/** /**
@@ -64,4 +67,43 @@ public class AVMServiceTest extends TestCase
public void testNothing() public void testNothing()
{ {
} }
/**
* Test making a simple directory.
*/
public void testCreateDirectory()
{
try
{
fService.createDirectory("main:/", "testdir");
ArrayList<String> toSnapshot = new ArrayList<String>();
toSnapshot.add("main");
fService.createSnapshot(toSnapshot);
}
catch (Exception e)
{
e.printStackTrace(System.err);
fail();
}
}
/**
* Test creating a file.
*/
public void testCreateFile()
{
try
{
testCreateDirectory();
fService.createFile("main:testdir", "testfile");
ArrayList<String> toSnapshot = new ArrayList<String>();
toSnapshot.add("main");
fService.createSnapshot(toSnapshot);
}
catch (Exception e)
{
e.printStackTrace(System.err);
fail();
}
}
} }

View File

@@ -4,10 +4,10 @@
<!-- AVMNodeBean is the abstract base for filesystem like objects. <!-- AVMNodeBean is the abstract base for filesystem like objects.
We're using the one table per class hierarchy strategy to implement We're using the one table per class hierarchy strategy to implement
polymorphism. --> polymorphism. -->
<class table="avm_nodes" lazy="true" abstract="true" <class table="avm_nodes" abstract="true"
name="AVMNodeBeanImpl" name="AVMNodeBeanImpl"
proxy="AVMNodeBean" proxy="AVMNodeBean"
optimistic-lock="version"> optimistic-lock="version" lazy="false">
<cache usage="read-write"/> <cache usage="read-write"/>
<!-- The id is set programmatically using an Issuer. See below. --> <!-- The id is set programmatically using an Issuer. See below. -->
<id name="id" column="id" type="long"/> <id name="id" column="id" type="long"/>
@@ -49,61 +49,65 @@
<!-- Directories, two flavors. --> <!-- Directories, two flavors. -->
<subclass name="DirectoryNodeBeanImpl" <subclass name="DirectoryNodeBeanImpl"
proxy="DirectoryNodeBean" proxy="DirectoryNodeBean"
abstract="true"> abstract="true"
lazy="false">
<!-- A Layered Directory is our smart symlink thingy. --> <!-- A Layered Directory is our smart symlink thingy. -->
<subclass <subclass name="LayeredDirectoryNodeBeanImpl"
name="LayeredDirectoryNodeBeanImpl" proxy="LayeredDirectoryNodeBean"
proxy="LayeredDirectoryNodeBean" discriminator-value="layereddirectory"> discriminator-value="layereddirectory" lazy="false">
<!-- The layer id is an implementation trick to disambiguate <!-- The layer id is an implementation trick to disambiguate
exactly what layer is being refered to in various circumstances. --> exactly what layer is being refered to in various circumstances. -->
<property name="layerID" column="layer_id" type="long" not-null="true"/> <property name="layerID" column="layer_id" type="long"
<!-- The is the moral equivalent of the value of a symlink. --> not-null="true" />
<property name="indirection" column="indirection" type="string" <!-- The is the moral equivalent of the value of a symlink. -->
length="511"/> <property name="indirection" column="indirection"
<!-- This marks a layered directory as either knowing itself what type="string" length="511" />
it points at (true) or inheriting what it points at from its <!-- This marks a layered directory as either knowing itself what
container (false). --> it points at (true) or inheriting what it points at from its
<property name="primaryIndirection" column="primary_indirection" type="boolean"/> container (false). -->
<!-- Map of names to DirectoryEntries. --> <property name="primaryIndirection"
<map name="added" cascade="all"> column="primary_indirection" type="boolean" />
<key column="directory_id"/> <!-- Map of names to DirectoryEntries. -->
<map-key type="string" column="name"/> <map name="added" cascade="all">
<!-- A DirectoryEntry is a (node)type AVMNode reference pair. <key column="directory_id" />
Should probably convert type into an integer code. --> <map-key type="string" column="name" />
<composite-element class="DirectoryEntry"> <!-- A DirectoryEntry is a (node)type AVMNode reference pair.
<property name="type" column="type_name" Should probably convert type into an integer code. -->
type="string" length="30" not-null="true"/> <composite-element class="DirectoryEntry">
<many-to-one name="child" <property name="type" column="type_name"
class="AVMNodeBeanImpl" type="string" length="30" not-null="true" />
cascade="save-update" not-null="true"> <many-to-one name="child"
</many-to-one> class="AVMNodeBeanImpl" cascade="save-update"
</composite-element> not-null="true">
</map> </many-to-one>
<!-- This is just the set of names of children deleted (and therefore </composite-element>
hidden) in this layer. --> </map>
<set name="deleted" table="deleted_children" <!-- This is just the set of names of children deleted (and therefore
fetch="join" cascade="all"> hidden) in this layer. -->
<key column="directory_id"/> <set name="deleted" table="deleted_children"
<element type="string" column="name"/> fetch="join" cascade="all">
</set> <key column="directory_id" />
</subclass> <element type="string" column="name" />
<!-- Just plain directories. --> </set>
</subclass>
<!-- Just plain directories. -->
<subclass name="PlainDirectoryNodeBeanImpl" <subclass name="PlainDirectoryNodeBeanImpl"
discriminator-value="plaindirectory" proxy="PlainDirectoryNodeBean"> discriminator-value="plaindirectory" proxy="PlainDirectoryNodeBean" lazy="false">
<!-- For reference count based garbage collection of purged nodes <!-- For reference count based garbage collection of purged nodes
to work we need to specially mark the root directory of to work we need to specially mark the root directory of
a Repository as special so that its absence of parents will a Repository as special so that its absence of parents will
not cause it to be vacuumed away. TODO: for ease of queries, not cause it to be vacuumed away. TODO: for ease of queries,
this probably wants to be in the base class. --> this probably wants to be in the base class. -->
<property name="isRoot" column="is_root" type="boolean"/> <property name="isRoot" column="is_root" type="boolean" />
<!-- A map of names to DirectoryEntries. In the AVM world, it makes sense <!-- A map of names to DirectoryEntries. In the AVM world, it makes sense
that nodes don't know there own names, only there containers do. --> that nodes don't know there own names, only there containers do. -->
<map name="children" cascade="all"> <map name="children" cascade="all">
<key column="directory_id"/> <key column="directory_id" />
<map-key type="string" column="name"/> <map-key type="string" column="name" />
<composite-element class="org.alfresco.repo.avm.hibernate.DirectoryEntry"> <composite-element
<property name="type" type="string" not-null="true" length="30" class="org.alfresco.repo.avm.hibernate.DirectoryEntry">
column="type_name"/> <property name="type" type="string"
not-null="true" length="30" column="type_name" />
<many-to-one name="child" <many-to-one name="child"
class="org.alfresco.repo.avm.hibernate.AVMNodeBeanImpl" class="org.alfresco.repo.avm.hibernate.AVMNodeBeanImpl"
not-null="true" cascade="save-update"> not-null="true" cascade="save-update">
@@ -115,19 +119,20 @@
<!-- There are two kinds of files, plain and symlinky. --> <!-- There are two kinds of files, plain and symlinky. -->
<subclass name="FileNodeBeanImpl" <subclass name="FileNodeBeanImpl"
proxy="FileNodeBean" proxy="FileNodeBean"
abstract="true"> abstract="true"
lazy="false">
<!-- Plain files just have a reference to a Content object. --> <!-- Plain files just have a reference to a Content object. -->
<subclass discriminator-value="plainfile" <subclass discriminator-value="plainfile"
name="PlainFileNodeBeanImpl" name="PlainFileNodeBeanImpl" proxy="PlainFileNodeBean" lazy="false">
proxy="PlainFileNodeBean">
<many-to-one name="content" column="content_id" <many-to-one name="content" column="content_id"
class="ContentBeanImpl" fetch="join" cascade="save-update"> class="ContentBeanImpl" fetch="join" cascade="save-update">
</many-to-one> </many-to-one>
</subclass> </subclass>
<!-- Layered files are almost exactly copy on write symlinks. --> <!-- Layered files are almost exactly copy on write symlinks. -->
<subclass name="LayeredFileNodeBeanImpl" <subclass name="LayeredFileNodeBeanImpl"
discriminator-value="layeredfile" proxy="LayeredFileNodeBean"> discriminator-value="layeredfile" proxy="LayeredFileNodeBean" lazy="false">
<property name="indirection" type="string" length="511" column="indirection"/> <property name="indirection" type="string" length="511"
column="indirection" />
</subclass> </subclass>
</subclass> </subclass>
</class> </class>

View File

@@ -222,4 +222,39 @@ public class BasicAttributesBeanImpl implements BasicAttributesBean
{ {
return fAccessDate; return fAccessDate;
} }
// TODO This is probably wrong.
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (fID == null)
{
return false;
}
if (!(obj instanceof BasicAttributesBean))
{
return false;
}
return fID == ((BasicAttributesBean)obj).getId();
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode()
{
if (fID == null)
{
return 0;
}
return fID.hashCode();
}
} }

View File

@@ -30,6 +30,25 @@ public class HibernateHelper
static static
{ {
Reset();
}
public static SessionFactory GetSessionFactory()
{
return fgFactory;
}
public static Configuration GetConfiguration()
{
return fgCfg;
}
public static void Reset()
{
if (fgFactory != null)
{
fgFactory.close();
}
try try
{ {
fgCfg = new Configuration(); fgCfg = new Configuration();
@@ -42,14 +61,4 @@ public class HibernateHelper
System.exit(1); System.exit(1);
} }
} }
public static SessionFactory GetSessionFactory()
{
return fgFactory;
}
public static Configuration GetConfiguration()
{
return fgCfg;
}
} }

View File

@@ -77,8 +77,8 @@ public class TestPopulate extends TestCase
{ {
// Set up issuers. // Set up issuers.
Issuer nodeIssuer = new Issuer("node", 0, session); Issuer nodeIssuer = new Issuer("node", 0, session);
Issuer contentIssuer = new Issuer("content", 0, session); new Issuer("content", 0, session);
Issuer repositoryIssuer = new Issuer("repository", 0, session); new Issuer("repository", 0, session);
// Make the initial root directory. // Make the initial root directory.
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt", BasicAttributesBean attrs = new BasicAttributesBeanImpl("britt",

View File

@@ -99,6 +99,7 @@ public class RepositoryImpl implements Repository
fData.setRoot(rootBean); fData.setRoot(rootBean);
fData.getRoots().put(fData.getNextVersionID(), rootBean); fData.getRoots().put(fData.getNextVersionID(), rootBean);
fData.setNextVersionID(fData.getNextVersionID()); fData.setNextVersionID(fData.getNextVersionID());
fSuper.getSession().save(fData);
} }
/** /**

View File

@@ -142,6 +142,8 @@ public class SuperRepositoryImpl implements SuperRepository
// Newing up the object causes it to be written to the db. // Newing up the object causes it to be written to the db.
@SuppressWarnings("unused") @SuppressWarnings("unused")
Repository rep = new RepositoryImpl(this, name); Repository rep = new RepositoryImpl(this, name);
// Special handling for repository creation.
rep.getDataBean().getRoot().setIsNew(false);
} }
/* (non-Javadoc) /* (non-Javadoc)
@@ -485,7 +487,7 @@ public class SuperRepositoryImpl implements SuperRepository
*/ */
private Repository getRepositoryByName(String name) private Repository getRepositoryByName(String name)
{ {
Query query = fSession.createQuery("from repositories r where r.name = :name"); Query query = fSession.createQuery("from RepositoryBeanImpl r where r.name = :name");
query.setString("name", name); query.setString("name", name);
return new RepositoryImpl(this, (RepositoryBean)query.uniqueResult()); return new RepositoryImpl(this, (RepositoryBean)query.uniqueResult());
} }