[hibernate-commits] Hibernate SVN: r10283 - in trunk/HibernateExt/metadata: lib src/java/org/hibernate/cfg src/java/org/hibernate/cfg/annotations src/test/org/hibernate/test/annotations src/test/org/hibernate/test/annotations/idmanytoone
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Fri Aug 18 15:53:45 EDT 2006
Author: epbernard
Date: 2006-08-18 15:53:41 -0400 (Fri, 18 Aug 2006)
New Revision: 10283
Added:
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/Card.java
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/CardField.java
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/CardKey.java
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/IdManyToOne.java
trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/Project.java
Modified:
trunk/HibernateExt/metadata/lib/ejb3-persistence.jar
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/FkSecondPass.java
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/TableBinder.java
trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java
Log:
ANN-382 Order FK setup to make it handle all non circular graphs
Modified: trunk/HibernateExt/metadata/lib/ejb3-persistence.jar
===================================================================
(Binary files differ)
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-08-18 15:17:00 UTC (rev 10282)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationBinder.java 2006-08-18 19:53:41 UTC (rev 10283)
@@ -1754,7 +1754,7 @@
mappings.addSecondPass(
new FkSecondPass(
value, columns,
- !optional && unique, //cannot have nullabe and unique on certain DBs
+ !optional && unique, //cannot have nullabe and unique on certain DBs like Derby
path, mappings
)
);
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java 2006-08-18 15:17:00 UTC (rev 10282)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/AnnotationConfiguration.java 2006-08-18 19:53:41 UTC (rev 10283)
@@ -278,20 +278,11 @@
}
caches.clear();
- log.debug( "processing manytoone fk mappings" );
+ processFkSecondPassInOrder();
Iterator iter = secondPasses.iterator();
while ( iter.hasNext() ) {
SecondPass sp = (SecondPass) iter.next();
//do the second pass of fk before the others and remove them
- if ( sp instanceof FkSecondPass ) {
- sp.doSecondPass( classes );
- iter.remove();
- }
- }
- iter = secondPasses.iterator();
- while ( iter.hasNext() ) {
- SecondPass sp = (SecondPass) iter.next();
- //do the second pass of fk before the others and remove them
if ( sp instanceof CreateKeySecondPass ) {
sp.doSecondPass( classes );
iter.remove();
@@ -330,6 +321,68 @@
}
}
+ private void processFkSecondPassInOrder() {
+ log.debug( "processing manytoone fk mappings" );
+ Iterator iter = secondPasses.iterator();
+ /* We need to process FKSecond pass trying to resolve any
+ * graph circularity (ie PK made of a many to one linking to
+ * an entity having a PK made of a ManyToOne ...
+ */
+ Set fkSecondPasses = new HashSet();
+ while ( iter.hasNext() ) {
+ SecondPass sp = (SecondPass) iter.next();
+ //do the second pass of fk before the others and remove them
+ if ( sp instanceof FkSecondPass ) {
+ fkSecondPasses.add(sp);
+ iter.remove();
+ }
+ }
+ if (fkSecondPasses.size() > 0) {
+ Map<String, Set<String>> isADependencyOf = new HashMap<String, Set<String>>();
+ List orderedFkSecondPasses = new ArrayList( fkSecondPasses.size() );
+ List orderedTable = new ArrayList( fkSecondPasses.size() );
+ Iterator it = fkSecondPasses.iterator();
+ while ( it.hasNext() ) {
+ FkSecondPass sp = (FkSecondPass) it.next();
+ String referenceEntityName = sp.getValue().getReferencedEntityName();
+ String dependentTable = getClassMapping( referenceEntityName ).getTable().getQuotedName();
+ if ( ! isADependencyOf.containsKey( dependentTable ) ) {
+ isADependencyOf.put( dependentTable, new HashSet<String>() );
+ }
+ String table = sp.getValue().getTable().getQuotedName();
+ isADependencyOf.get( dependentTable ).add( table );
+ int beAfter = orderedTable.indexOf( dependentTable );
+ int beBefore = orderedFkSecondPasses.size();
+ Set<String> dependencies = isADependencyOf.get( table );
+ if (dependencies != null) {
+ for ( String tableDep : dependencies ) {
+ //for each declared dependency take the lowest index
+ int index = orderedTable.indexOf( tableDep );
+ //index = -1 when we have a self dependency
+ beBefore = index != -1 && index < beBefore ? index : beBefore;
+ }
+ }
+ int currentIndex = orderedTable.indexOf( table );
+ if (beBefore < beAfter ||
+ (currentIndex != -1 && ( currentIndex < beAfter || currentIndex > beBefore ) )
+ ) {
+ StringBuilder sb = new StringBuilder("Foreign key circularity dependency involving the following tables: ");
+ sb.append( table );
+ if (beAfter > -1) sb.append(", ").append( dependentTable );
+ if ( beBefore < orderedFkSecondPasses.size() ) sb.append(", ").append( orderedTable.get(beBefore) );
+ throw new AnnotationException( sb.toString() );
+ }
+ currentIndex = currentIndex == -1 ? beBefore : currentIndex;
+ orderedTable.add( currentIndex, table );
+ orderedFkSecondPasses.add( currentIndex, sp );
+ }
+ it = orderedFkSecondPasses.listIterator();
+ while ( it.hasNext() ) {
+ ( (SecondPass) it.next() ).doSecondPass( classes );
+ }
+ }
+ }
+
private void processArtifactsOfType(String artifact) {
if ( "hbm".equalsIgnoreCase( artifact ) ) {
log.debug( "Process hbm files" );
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/FkSecondPass.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/FkSecondPass.java 2006-08-18 15:17:00 UTC (rev 10282)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/FkSecondPass.java 2006-08-18 19:53:41 UTC (rev 10283)
@@ -8,7 +8,7 @@
import org.hibernate.mapping.ManyToOne;
import org.hibernate.mapping.OneToOne;
import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Value;
+import org.hibernate.mapping.ToOne;
/**
* Enable a proper set of the FK columns in respect with the id column order
@@ -18,13 +18,13 @@
* @author Emmanuel Bernard
*/
public class FkSecondPass implements SecondPass {
- private Value value;
+ private ToOne value;
private Ejb3JoinColumn[] columns;
private boolean unique;
private ExtendedMappings mappings;
private String path;
- FkSecondPass(Value value, Ejb3JoinColumn[] columns, boolean unique, String path, ExtendedMappings mappings) {
+ FkSecondPass(ToOne value, Ejb3JoinColumn[] columns, boolean unique, String path, ExtendedMappings mappings) {
this.mappings = mappings;
this.value = value;
this.columns = columns;
@@ -32,6 +32,10 @@
this.path = path;
}
+ public ToOne getValue() {
+ return value;
+ }
+
public void doSecondPass(java.util.Map persistentClasses) throws MappingException {
if ( value instanceof ManyToOne ) {
ManyToOne manyToOne = (ManyToOne) value;
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/TableBinder.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/TableBinder.java 2006-08-18 15:17:00 UTC (rev 10282)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/TableBinder.java 2006-08-18 19:53:41 UTC (rev 10283)
@@ -293,7 +293,7 @@
break;
}
}
- if ( match == false ) {
+ if ( !match ) {
throw new AnnotationException(
"Column name " + col.getName() + " of "
+ referencedEntity.getEntityName() + " not found in JoinColumns.referencedColumnName"
Modified: trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java
===================================================================
--- trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java 2006-08-18 15:17:00 UTC (rev 10282)
+++ trunk/HibernateExt/metadata/src/java/org/hibernate/cfg/annotations/Version.java 2006-08-18 19:53:41 UTC (rev 10283)
@@ -8,7 +8,7 @@
* @author Emmanuel Bernard
*/
public class Version {
- public static String VERSION = "3.2.0.CR1";
+ public static String VERSION = "3.2.0.CR2";
private static Log log = LogFactory.getLog( Version.class );
static {
Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/Card.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/Card.java 2006-08-18 15:17:00 UTC (rev 10282)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/Card.java 2006-08-18 19:53:41 UTC (rev 10283)
@@ -0,0 +1,29 @@
+//$Id: $
+package org.hibernate.test.annotations.idmanytoone;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Embeddable;
+import javax.persistence.ManyToOne;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class Card {
+
+ @Id
+ private CardPrimaryKey primaryKey = new CardPrimaryKey();
+
+ @Embeddable
+ private class CardPrimaryKey implements Serializable {
+
+ @ManyToOne(optional = false)
+ private Project project;
+
+ //An other @ManyToOne is also present in the real model
+ //The problem still occurs even when i remove this relation, it was no use to kept it for describe the problem
+
+ }
+}
Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/CardField.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/CardField.java 2006-08-18 15:17:00 UTC (rev 10282)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/CardField.java 2006-08-18 19:53:41 UTC (rev 10283)
@@ -0,0 +1,32 @@
+//$Id: $
+package org.hibernate.test.annotations.idmanytoone;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+import javax.persistence.Embeddable;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class CardField {
+
+ @Id
+ private PrimaryKey primaryKey = new PrimaryKey();
+
+ @ManyToOne
+ private Card cardtmp;
+
+ @Embeddable
+ private class PrimaryKey implements Serializable {
+
+ @ManyToOne(optional = false)
+ private Card card;
+
+ @ManyToOne(optional = false)
+ private CardKey key;
+ }
+}
+
Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/CardKey.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/CardKey.java 2006-08-18 15:17:00 UTC (rev 10282)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/CardKey.java 2006-08-18 19:53:41 UTC (rev 10283)
@@ -0,0 +1,16 @@
+//$Id: $
+package org.hibernate.test.annotations.idmanytoone;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class CardKey {
+ @Id
+ @GeneratedValue
+ private int id;
+}
Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/IdManyToOne.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/IdManyToOne.java 2006-08-18 15:17:00 UTC (rev 10282)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/IdManyToOne.java 2006-08-18 19:53:41 UTC (rev 10283)
@@ -0,0 +1,25 @@
+//$Id: $
+package org.hibernate.test.annotations.idmanytoone;
+
+import org.hibernate.Session;
+import org.hibernate.test.annotations.TestCase;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class IdManyToOne extends TestCase {
+ public void testFkCreationOrdering() throws Exception {
+ //no real test case, the sessionFactory building is tested
+ Session s = openSession();
+ s.close();
+ }
+
+ protected Class[] getMappings() {
+ return new Class[] {
+ CardKey.class,
+ CardField.class,
+ Card.class,
+ Project.class
+ };
+ }
+}
Added: trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/Project.java
===================================================================
--- trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/Project.java 2006-08-18 15:17:00 UTC (rev 10282)
+++ trunk/HibernateExt/metadata/src/test/org/hibernate/test/annotations/idmanytoone/Project.java 2006-08-18 19:53:41 UTC (rev 10283)
@@ -0,0 +1,17 @@
+//$Id: $
+package org.hibernate.test.annotations.idmanytoone;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.GeneratedValue;
+
+/**
+ * @author Emmanuel Bernard
+ */
+ at Entity
+public class Project {
+
+ @Id
+ @GeneratedValue
+ private int id;
+}
More information about the hibernate-commits
mailing list