Author: brj
Date: Sat Jan 21 04:33:57 2006
New Revision: 371022
URL: http://svn.apache.org/viewcvs?rev=371022&view=rev
Log:
no longer create OUTER join when both ends of a relationship point to same class
Modified:
db/ojb/trunk/release-notes.txt
db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/TableAliasHandler.java
db/ojb/trunk/src/schema/ojbtest-schema.xml
db/ojb/trunk/src/test/org/apache/ojb/broker/CollectionTest2.java
db/ojb/trunk/src/test/org/apache/ojb/repository_junit_reference.xml
Modified: db/ojb/trunk/release-notes.txt
URL:
http://svn.apache.org/viewcvs/db/ojb/trunk/release-notes.txt?rev=371022&r1=371021&r2=371022&view=diff
==============================================================================
--- db/ojb/trunk/release-notes.txt (original)
+++ db/ojb/trunk/release-notes.txt Sat Jan 21 04:33:57 2006
@@ -98,7 +98,9 @@
--
CHANGES:
-
+- OJB no longer generates OUTER joins when both ends of a relationship point
to the same class.
+ Use setPathOuterJoin("path") to force an OUTER join.
+
- replaced ojbConcreteClass by a discriminator-descriptor:
<class-descriptor
Modified:
db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/TableAliasHandler.java
URL:
http://svn.apache.org/viewcvs/db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/TableAliasHandler.java?rev=371022&r1=371021&r2=371022&view=diff
==============================================================================
---
db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/TableAliasHandler.java
(original)
+++
db/ojb/trunk/src/java/org/apache/ojb/broker/accesslayer/sql/TableAliasHandler.java
Sat Jan 21 04:33:57 2006
@@ -373,7 +373,6 @@
Object[] prevKeys;
Object[] keys;
ArrayList descriptors;
- boolean outer = useOuterJoins;
int pathLength;
List hintClasses = null;
String pathAlias = aUserAlias == null ? null :
aUserAlias.getAlias(aPath);
@@ -411,6 +410,7 @@
pathLength = descriptors.size();
for (int i = 0; i < pathLength; i++)
{
+ boolean outer = useOuterJoins;
if (!(descriptors.get(i) instanceof
ObjectReferenceDescriptor))
{
// only use Collection- and
ObjectReferenceDescriptor
@@ -509,7 +509,8 @@
{
curr = createTableAlias(cld, attrPath, pathAlias, hintClasses);
- outer = outer || (curr.cld == prev.cld) ||
curr.hasExtents() || useOuterJoins;
+ // BRJ: use OUTER join for extents
+ outer = outer || curr.hasExtents();
addJoin(prev, prevKeys, curr, keys, outer,
attr);
buildSuperJoinTree(curr, cld, aPath, outer);
Modified: db/ojb/trunk/src/schema/ojbtest-schema.xml
URL:
http://svn.apache.org/viewcvs/db/ojb/trunk/src/schema/ojbtest-schema.xml?rev=371022&r1=371021&r2=371022&view=diff
==============================================================================
--- db/ojb/trunk/src/schema/ojbtest-schema.xml (original)
+++ db/ojb/trunk/src/schema/ojbtest-schema.xml Sat Jan 21 04:33:57 2006
@@ -1157,6 +1157,23 @@
</foreign-key>
</table>
+ <table name="COL_2_SUB_PROJECT_SELF">
+ <column name="SUB_ID" required="true" primaryKey="true"
type="INTEGER"/>
+ <column name="NAME" type="VARCHAR" size="150"/>
+ <column name="FK_PRO_ID" type="INTEGER"/>
+ <foreign-key foreignTable="COL_2_SUB_PROJECT_SELF">
+ <reference local="FK_PRO_ID" foreign="SUB_ID"/>
+ </foreign-key>
+ </table>
+ <table name="COL_2_DEVELOPER_SELF">
+ <column name="DEV_ID" required="true" primaryKey="true"
type="INTEGER"/>
+ <column name="NAME" type="VARCHAR" size="150"/>
+ <column name="FK_PRO_ID" type="INTEGER"/>
+ <foreign-key foreignTable="COL_2_SUB_PROJECT_SELF">
+ <reference local="FK_PRO_ID" foreign="SUB_ID"/>
+ </foreign-key>
+ </table>
+
<!-- =================================================== -->
<!-- PBListenerTest test -->
<!-- =================================================== -->
Modified: db/ojb/trunk/src/test/org/apache/ojb/broker/CollectionTest2.java
URL:
http://svn.apache.org/viewcvs/db/ojb/trunk/src/test/org/apache/ojb/broker/CollectionTest2.java?rev=371022&r1=371021&r2=371022&view=diff
==============================================================================
--- db/ojb/trunk/src/test/org/apache/ojb/broker/CollectionTest2.java (original)
+++ db/ojb/trunk/src/test/org/apache/ojb/broker/CollectionTest2.java Sat Jan 21
04:33:57 2006
@@ -7,12 +7,15 @@
import java.util.List;
import org.apache.commons.lang.SerializationUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.ojb.broker.accesslayer.sql.SqlGenerator;
import org.apache.ojb.broker.core.proxy.ProxyFactory;
import org.apache.ojb.broker.metadata.ClassDescriptor;
import org.apache.ojb.broker.metadata.CollectionDescriptor;
import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
import org.apache.ojb.broker.query.Criteria;
import org.apache.ojb.broker.query.Query;
+import org.apache.ojb.broker.query.QueryByCriteria;
import org.apache.ojb.broker.query.QueryFactory;
import org.apache.ojb.junit.PBTestCase;
@@ -689,6 +692,95 @@
result = broker.getCollectionByQuery(queryDeveloper);
assertEquals(0, result.size());
}
+
+ public void testSelfReference()
+ {
+ changeAutoSetting(SubProjectSelfRef.class, "subProjects", true,
CollectionDescriptor.CASCADE_OBJECT,
+ CollectionDescriptor.CASCADE_NONE, false);
+ changeAutoSetting(SubProjectSelfRef.class, "developers", true,
CollectionDescriptor.CASCADE_OBJECT,
+ CollectionDescriptor.CASCADE_NONE, false);
+
+ String name = "testSelfReference" + System.currentTimeMillis();
+
+ DeveloperSelf dev1 = new DeveloperSelf(name + "A");
+ DeveloperSelf dev2 = new DeveloperSelf(name + "B");
+ DeveloperSelf dev3 = new DeveloperSelf(name + "C");
+ ArrayList devList = new ArrayList();
+ devList.add(dev1);
+ devList.add(dev2);
+ ArrayList sub1devList = new ArrayList();
+ sub1devList.add(dev3);
+
+ SubProjectSelfRef sub1 = new SubProjectSelfRef(name + "A");
+ SubProjectSelfRef sub2 = new SubProjectSelfRef(name + "B");
+ ArrayList subList = new ArrayList();
+ subList.add(sub1);
+ subList.add(sub2);
+
+ SubProjectSelfRef pro = new SubProjectSelfRef(name + "MAIN");
+ pro.setSubProjects(subList);
+ pro.setDevelopers(devList);
+ sub1.setDevelopers(sub1devList);
+
+ Query queryProject = createQueryFor(SubProjectSelfRef.class, "name",
name + "MAIN");
+ Query querySubProject = createQueryFor(SubProjectSelfRef.class,
"name", name);
+ Query queryDeveloper = createQueryFor(DeveloperSelf.class, "name",
name);
+
+ //*****************************************
+ // insert
+ //*****************************************
+ broker.beginTransaction();
+ broker.store(pro);
+ broker.commitTransaction();
+
+ broker.clearCache();
+ Collection result = broker.getCollectionByQuery(queryProject);
+ assertEquals(1, result.size());
+ assertNotNull(result.iterator().next());
+ result = broker.getCollectionByQuery(querySubProject);
+ assertEquals(3, result.size());
+ result = broker.getCollectionByQuery(queryDeveloper);
+ assertEquals(3, result.size());
+
+ //*****************************************
+ // query using relationships
+ //*****************************************
+
+ // generates INNER joins between COL_2_SUB_PROJECT_SELF and
COL_2_DEVELOPER_SELF
+ QueryByCriteria queryByDeveloper =
createQueryFor(SubProjectSelfRef.class, "developers.name", name);
+ queryByDeveloper.setDistinct(true);
+ result = broker.getCollectionByQuery(queryByDeveloper);
+ assertEquals(2, result.size());
+
+ // generates INNER joins between COL_2_SUB_PROJECT_SELF and
COL_2_SUB_PROJECT_SELF and COL_2_DEVELOPER_SELF
+ QueryByCriteria queryBySubDeveloper =
createQueryFor(SubProjectSelfRef.class, "subProjects.developers.name",
+ dev3.getName());
+ queryBySubDeveloper.setDistinct(true);
+ result = broker.getCollectionByQuery(queryBySubDeveloper);
+ assertEquals(1, result.size());
+
+ ClassDescriptor cd =
broker.getClassDescriptor(queryBySubDeveloper.getBaseClass());
+ SqlGenerator sqlg = broker.serviceSqlGenerator();
+ String sql = sqlg.getPreparedSelectStatement(queryBySubDeveloper,
cd).getStatement();
+ assertFalse(sql.contains("OUTER JOIN"));
+ assertTrue(sql.contains("INNER JOIN"));
+
+ // generates OUTER joins between COL_2_SUB_PROJECT_SELF and
COL_2_SUB_PROJECT_SELF and COL_2_DEVELOPER_SELF
+ QueryByCriteria queryBySubDeveloper2 =
createQueryFor(SubProjectSelfRef.class, "subProjects.developers.name",
+ dev3.getName());
+ queryBySubDeveloper2.setDistinct(true);
+ queryBySubDeveloper2.setPathOuterJoin("subProjects");
+ queryBySubDeveloper2.setPathOuterJoin("subProjects.developers");
+ result = broker.getCollectionByQuery(queryBySubDeveloper2);
+ assertEquals(1, result.size());
+
+ cd = broker.getClassDescriptor(queryBySubDeveloper2.getBaseClass());
+ sqlg = broker.serviceSqlGenerator();
+ sql = sqlg.getPreparedSelectStatement(queryBySubDeveloper2,
cd).getStatement();
+ assertTrue(sql.contains("OUTER JOIN"));
+ assertFalse(sql.contains("INNER JOIN"));
+ }
+
//============================================================================
// helper methods
@@ -716,7 +808,7 @@
ref.setCascadingDelete(autoDelete);
}
- Query createQueryFor(Class clazz, String attribute, String value)
+ QueryByCriteria createQueryFor(Class clazz, String attribute, String value)
{
Criteria crit = new Criteria();
crit.addLike(attribute, "%" + value + "%");
@@ -856,6 +948,64 @@
public void setProject(ProjectIF project);
}
+ public static class SubProjectSelfRef
+ {
+ private Integer id;
+ private String name;
+ private List subProjects;
+ private Collection developers;
+
+ public SubProjectSelfRef()
+ {
+ }
+
+ public SubProjectSelfRef(String name)
+ {
+ this.name = name;
+ }
+
+ public Integer getId()
+ {
+ return id;
+ }
+
+ public void setId(Integer id)
+ {
+ this.id = id;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ private Collection getDevelopers()
+ {
+ return developers;
+ }
+
+ private void setDevelopers(Collection developers)
+ {
+ this.developers = developers;
+ }
+
+ private List getSubProjects()
+ {
+ return subProjects;
+ }
+
+ private void setSubProjects(List subProjects)
+ {
+ this.subProjects = subProjects;
+ }
+ }
+
+
public static class Developer implements Serializable
{
private Integer id;
@@ -899,6 +1049,19 @@
public void setProjectId(Integer projectId)
{
this.projectId = projectId;
+ }
+ }
+
+ public static class DeveloperSelf extends Developer
+ {
+ public DeveloperSelf()
+ {
+ super();
+ }
+
+ public DeveloperSelf(String name)
+ {
+ super(name);
}
}
}
Modified: db/ojb/trunk/src/test/org/apache/ojb/repository_junit_reference.xml
URL:
http://svn.apache.org/viewcvs/db/ojb/trunk/src/test/org/apache/ojb/repository_junit_reference.xml?rev=371022&r1=371021&r2=371022&view=diff
==============================================================================
--- db/ojb/trunk/src/test/org/apache/ojb/repository_junit_reference.xml
(original)
+++ db/ojb/trunk/src/test/org/apache/ojb/repository_junit_reference.xml Sat Jan
21 04:33:57 2006
@@ -1512,7 +1512,7 @@
<fk-pointing-to-element-class column="ACTOR_ID"/>
<fk-pointing-to-element-class column="ACTOR_ID2"/>
</collection-descriptor>
-
+
<collection-descriptor
name="actors2"
element-class-ref="org.apache.ojb.broker.M2NTest$Actor"
@@ -1842,6 +1842,80 @@
/>
</class-descriptor>
+ <class-descriptor
+ class="org.apache.ojb.broker.CollectionTest2$SubProjectSelfRef"
+ table="COL_2_SUB_PROJECT_SELF"
+ >
+
+ <field-descriptor
+ name="id"
+ column="SUB_ID"
+ jdbc-type="INTEGER"
+ primarykey="true"
+ autoincrement="true"
+ />
+
+ <field-descriptor
+ name="name"
+ column="NAME"
+ jdbc-type="VARCHAR"
+ />
+
+ <field-descriptor
+ name="projectId"
+ column="FK_PRO_ID"
+ jdbc-type="INTEGER"
+ access="anonymous"
+ />
+
+ <collection-descriptor
+ name="developers"
+
element-class-ref="org.apache.ojb.broker.CollectionTest2$DeveloperSelf"
+ proxy="false"
+ auto-retrieve="false"
+ auto-update="none"
+ auto-delete="none"
+ >
+ <inverse-foreignkey field-ref="projectId"/>
+ </collection-descriptor>
+
+ <collection-descriptor
+ name="subProjects"
+
element-class-ref="org.apache.ojb.broker.CollectionTest2$SubProjectSelfRef"
+ proxy="false"
+ auto-retrieve="false"
+ auto-update="none"
+ auto-delete="none"
+ >
+ <inverse-foreignkey field-ref="projectId"/>
+ </collection-descriptor>
+ </class-descriptor>
+
+ <class-descriptor
+ class="org.apache.ojb.broker.CollectionTest2$DeveloperSelf"
+ table="COL_2_DEVELOPER_SELF"
+ >
+
+ <field-descriptor
+ name="id"
+ column="DEV_ID"
+ jdbc-type="INTEGER"
+ primarykey="true"
+ autoincrement="true"
+ />
+
+ <field-descriptor
+ name="name"
+ column="NAME"
+ jdbc-type="VARCHAR"
+ />
+
+ <field-descriptor
+ name="projectId"
+ column="FK_PRO_ID"
+ jdbc-type="INTEGER"
+ />
+ </class-descriptor>
<!-- ************************************************* -->
<!-- M2NGraphTest -->
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]