### Eclipse Workspace Patch 1.0 #P org.hibernate.eclipse.jdt.ui Index: src/org/hibernate/eclipse/jdt/ui/wizards/ConfigurationActor.java =================================================================== --- src/org/hibernate/eclipse/jdt/ui/wizards/ConfigurationActor.java (revision 20828) +++ src/org/hibernate/eclipse/jdt/ui/wizards/ConfigurationActor.java (working copy) @@ -16,6 +16,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Set; import java.util.Map.Entry; @@ -173,6 +174,12 @@ if (pc != null){ if (pc.isAbstract()){ subclass = new SingleTableSubclass(pc); + if (pc instanceof RootClass && pc.getDiscriminator() == null){ + SimpleValue discr = new SimpleValue(); + discr.setTypeName("string"); //$NON-NLS-1$ + discr.addColumn(new Column("DISCR_COL")); //$NON-NLS-1$ + ((RootClass)pc).setDiscriminator(discr); + } } else { subclass = new JoinedSubclass(pc); } @@ -191,11 +198,11 @@ if (subclass instanceof JoinedSubclass) { ((JoinedSubclass) subclass).setTable(new Table(pastClass.getClassName().toUpperCase())); ((JoinedSubclass) subclass).setKey((KeyValue) pc.getIdentifierProperty().getValue()); - } else { - if (pastClass.getIdentifierProperty() != null) { - subclass.addProperty(pastClass.getIdentifierProperty()); - } } + if (pastClass.getIdentifierProperty() != null) { + subclass.addProperty(pastClass.getIdentifierProperty()); + } + Iterator it = pastClass.getPropertyIterator(); while (it.hasNext()) { subclass.addProperty((Property) it.next()); @@ -255,6 +262,8 @@ */ protected EntityInfo entityInfo; + private TypeDeclaration currentType; + TypeVisitor typeVisitor; public void setEntities(Map entities) { @@ -286,42 +295,48 @@ @Override public boolean visit(CompilationUnit node) { Assert.isNotNull(rootClass); + currentType = null; return true; } @SuppressWarnings("unchecked") public boolean visit(TypeDeclaration node) { - if ("".equals(entityInfo.getPrimaryIdName())){ //$NON-NLS-1$ - //try to guess id - FieldDeclaration[] fields = node.getFields(); - String firstFieldName = ""; //$NON-NLS-1$ - for (int i = 0; i < fields.length; i++) { - Iterator itFieldsNames = fields[i].fragments().iterator(); - while(itFieldsNames.hasNext()) { - VariableDeclarationFragment variable = itFieldsNames.next(); - Type type = ((FieldDeclaration)variable.getParent()).getType(); - if ("id".equals(variable.getName().getIdentifier()) //$NON-NLS-1$ - && !type.isArrayType() - && !Utils.isImplementInterface(new ITypeBinding[]{type.resolveBinding()}, Collection.class.getName())){ - entityInfo.setPrimaryIdName(variable.getName().getIdentifier()); - return true; - } else if ("".equals(firstFieldName)//$NON-NLS-1$ - && !type.isArrayType() - && !Utils.isImplementInterface( - new ITypeBinding[]{type.resolveBinding()}, Collection.class.getName())){ - //set first field as id - firstFieldName = variable.getName().getIdentifier(); + if (currentType == null){ + currentType = node; + if ("".equals(entityInfo.getPrimaryIdName())){ //$NON-NLS-1$ + //try to guess id + FieldDeclaration[] fields = node.getFields(); + String firstFieldName = ""; //$NON-NLS-1$ + for (int i = 0; i < fields.length; i++) { + Iterator itFieldsNames = fields[i].fragments().iterator(); + while(itFieldsNames.hasNext()) { + VariableDeclarationFragment variable = itFieldsNames.next(); + Type type = ((FieldDeclaration)variable.getParent()).getType(); + if ("id".equals(variable.getName().getIdentifier()) //$NON-NLS-1$ + && !type.isArrayType() + && !Utils.isImplementInterface(new ITypeBinding[]{type.resolveBinding()}, Collection.class.getName())){ + entityInfo.setPrimaryIdName(variable.getName().getIdentifier()); + return true; + } else if ("".equals(firstFieldName)//$NON-NLS-1$ + && !type.isArrayType() + && !Utils.isImplementInterface( + new ITypeBinding[]{type.resolveBinding()}, Collection.class.getName())){ + //set first field as id + firstFieldName = variable.getName().getIdentifier(); + } } } + entityInfo.setPrimaryIdName(firstFieldName); } - entityInfo.setPrimaryIdName(firstFieldName); + return true; } - return true; + //do not visit inner type + return false; } @Override public void endVisit(TypeDeclaration node) { - if (rootClass.getIdentifierProperty() == null){ + if (currentType == node && rootClass.getIdentifierProperty() == null){ //root class should always has id SimpleValue sValue = new SimpleValue(); sValue.addColumn(new Column("id".toUpperCase()));//$NON-NLS-1$ @@ -348,7 +363,9 @@ if (prop == null) { continue; } - + if (!varHasGetterAndSetter(var)){ + prop.setPropertyAccessorName("field"); //$NON-NLS-1$ + } String name = var.getName().getIdentifier(); if (name.equals(primaryIdName)) { rootClass.setIdentifierProperty(prop); @@ -360,6 +377,28 @@ return true; } + private boolean varHasGetterAndSetter(VariableDeclarationFragment var){ + String name = var.getName().getIdentifier(); + String setterName = "set" + Character.toUpperCase(name.charAt(0)) + name.substring(1); //$NON-NLS-1$ + String getterName = "get" + Character.toUpperCase(name.charAt(0)) + name.substring(1); //$NON-NLS-1$ + String getterName2 = null; + Type varType = ((FieldDeclaration)var.getParent()).getType(); + if (varType.isPrimitiveType() + && ((PrimitiveType)varType).getPrimitiveTypeCode() == PrimitiveType.BOOLEAN){ + getterName2 = "is" + Character.toUpperCase(name.charAt(0)) + name.substring(1); //$NON-NLS-1$ + } + boolean setterFound = false, getterFound = false; + MethodDeclaration[] mds = ((TypeDeclaration)((FieldDeclaration)var.getParent()).getParent()).getMethods(); + for (MethodDeclaration methodDeclaration : mds) { + String methodName = methodDeclaration.getName().getIdentifier(); + if (methodName.equals(setterName)) setterFound = true; + if (methodName.equals(getterName)) getterFound = true; + if (methodName.equals(getterName2)) getterFound = true; + if (setterFound && getterFound) return true; + } + return false; + } + @Override public boolean visit(MethodDeclaration node) { if (!entityInfo.isInterfaceFlag()) return super.visit(node); @@ -398,7 +437,7 @@ protected Property createProperty(String varName, Type varType) { typeVisitor.init(varName, entityInfo); varType.accept(typeVisitor); - Property p = typeVisitor.getProperty(); + Property p = typeVisitor.getProperty(); return p; } @@ -561,7 +600,14 @@ ((IndexedCollection)value).setIndex(map_key); } prop.setCascade("none");//$NON-NLS-1$ - } else if (ref != null){ + } else if (tb.isEnum()){ + value = buildSimpleValue(org.hibernate.type.EnumType.class.getName()); + Properties typeParameters = new Properties(); + typeParameters.put(org.hibernate.type.EnumType.ENUM, tb.getBinaryName()); + typeParameters.put(org.hibernate.type.EnumType.TYPE, java.sql.Types.VARCHAR); + ((SimpleValue)value).setTypeParameters(typeParameters); + buildProperty(value); + } else if (ref != null /*&& ref.fullyQualifiedName.indexOf('$') < 0*/){ ToOne sValue = null; if (ref.refType == RefType.MANY2ONE){ sValue = new ManyToOne(rootClass.getTable()); @@ -578,8 +624,7 @@ sValue.addColumn(column); sValue.setTypeName(tb.getBinaryName()); sValue.setFetchMode(FetchMode.JOIN); - RootClass associatedClass = rootClasses.get(ref.fullyQualifiedName); - sValue.setReferencedEntityName(associatedClass.getEntityName()); + sValue.setReferencedEntityName(ref.fullyQualifiedName); buildProperty(sValue); prop.setCascade("none");//$NON-NLS-1$ } else { Index: src/org/hibernate/eclipse/jdt/ui/internal/jpa/collect/CollectEntityInfo.java =================================================================== --- src/org/hibernate/eclipse/jdt/ui/internal/jpa/collect/CollectEntityInfo.java (revision 20828) +++ src/org/hibernate/eclipse/jdt/ui/internal/jpa/collect/CollectEntityInfo.java (working copy) @@ -475,12 +475,7 @@ String entityFullyQualifiedName = ""; //$NON-NLS-1$ if (tb.getJavaElement() instanceof SourceType) { SourceType sourceT = (SourceType)tb.getJavaElement(); - try { - entityFullyQualifiedName = sourceT.getFullyQualifiedParameterizedName(); - } - catch (JavaModelException e) { - HibernateConsolePlugin.getDefault().logErrorMessage("JavaModelException: ", e); //$NON-NLS-1$ - } + entityFullyQualifiedName = sourceT.getFullyQualifiedName(); entityInfo.addDependency(entityFullyQualifiedName); Iterator itVarNames = list.iterator(); while (itVarNames.hasNext()) { #P org.hibernate.eclipse.jdt.ui.test Index: src/org/hibernate/eclipse/jdt/ui/test/hbmexporter/HbmExporterTest.java =================================================================== --- src/org/hibernate/eclipse/jdt/ui/test/hbmexporter/HbmExporterTest.java (revision 21531) +++ src/org/hibernate/eclipse/jdt/ui/test/hbmexporter/HbmExporterTest.java (working copy) @@ -36,6 +36,7 @@ import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PrimitiveArray; import org.hibernate.mapping.Property; +import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.Value; import org.hibernate.type.IntegerType; @@ -203,7 +204,61 @@ assertEquals("string", map.getKey().getType().getName()); //$NON-NLS-1$ } + public void testEnum(){ + Configuration config = getConfigurationFor("pack.A"); //$NON-NLS-1$ + checkClassesMaped(config, "pack.A", "pack.B"); //$NON-NLS-1$ //$NON-NLS-2$ + PersistentClass b = config.getClassMapping("pack.B"); //$NON-NLS-1$ + + Property setProp = b.getProperty("state"); //$NON-NLS-1$ + Value value = setProp.getValue(); + assertNotNull(value); + assertTrue("Expected to get SimpleValue value", //$NON-NLS-1$ + value.getClass()==SimpleValue.class); + SimpleValue sv = (SimpleValue)value; + assertTrue("Expected to get Enum-type mapping", //$NON-NLS-1$ + org.hibernate.type.EnumType.class.getName().equals(sv.getTypeName())); + assertTrue("Expected to get pack.State class mapping", //$NON-NLS-1$ + sv.getTypeParameters().getProperty("enumClass").equals("pack.State")); + } + + public void testAccessField(){ + Configuration config = getConfigurationFor("pack.B"); //$NON-NLS-1$ + checkClassesMaped(config, "pack.B"); //$NON-NLS-1$ + PersistentClass b = config.getClassMapping("pack.B"); //$NON-NLS-1$ + Property bId= b.getIdentifierProperty(); + assertNotNull(bId); + assertEquals("field", bId.getPropertyAccessorName()); //$NON-NLS-1$ + } + + public void testInner(){ + Configuration config = getConfigurationFor("pack.B"); //$NON-NLS-1$ + PersistentClass b = config.getClassMapping("pack.B"); //$NON-NLS-1$ + + Property prop = b.getProperty("inner"); + assertNotNull(prop); + assertTrue(prop.getValue() instanceof SimpleValue); + assertEquals("pack.B$Inner", ((SimpleValue)prop.getValue()).getTypeName()); //$NON-NLS-1$ + } + + public void testClassHierarchy(){ + Configuration config = getConfigurationFor("pack.C"); //$NON-NLS-1$ + checkClassesMaped(config, "pack.A", "pack.B", "pack.C"); //$NON-NLS-1$ //$NON-NLS-2$ + PersistentClass a = config.getClassMapping("pack.A"); //$NON-NLS-1$ + PersistentClass c = config.getClassMapping("pack.C"); //$NON-NLS-1$ + + assertTrue("Class A should be abstract", a.isAbstract()); + assertEquals("Class A should be the superclass of class C", a, c.getSuperclass()); + assertNotNull("Class A should have a discriminator", a.getDiscriminator()); + } + + public void testDiscriminator(){ + Configuration config = getConfigurationFor("pack.C"); //$NON-NLS-1$ + PersistentClass a = config.getClassMapping("pack.A"); //$NON-NLS-1$ + + assertNotNull("Class A should have a discriminator", a.getDiscriminator()); + } + protected void createTestProject() throws JavaModelException, CoreException, IOException { project = new TestProject(PROJECT_NAME); Index: res/hbm/pack/C.java =================================================================== --- res/hbm/pack/C.java (revision 0) +++ res/hbm/pack/C.java (revision 0) @@ -0,0 +1,7 @@ +package pack; + +public class C extends A { + + String cField; + +} Index: res/hbm/pack/B.java =================================================================== --- res/hbm/pack/B.java (revision 21531) +++ res/hbm/pack/B.java (working copy) @@ -1,12 +1,27 @@ package pack; -/** - * @author Emmanuel Bernard - */ -public class B { - private String id; +import java.io.Serializable; + + +public class B { + + private Integer id; + private Inner inner; private int[] testIntArray; + private State state = State.AGREED; + + + public static class Inner implements Serializable { + private Long categoryId; + private Long itemId; + + public Inner(Long categoryId, Long itemId) { + this.categoryId = categoryId; + this.itemId = itemId; + } + } + public int[] getTestIntArray() { return testIntArray; } @@ -15,11 +30,7 @@ this.testIntArray = testIntArray; } - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } + + public State getState() { return state; } + public void setState(State state) { this.state = state; } } Index: res/hbm/pack/A.java =================================================================== --- res/hbm/pack/A.java (revision 21531) +++ res/hbm/pack/A.java (working copy) @@ -7,7 +7,7 @@ /** * @author Emmanuel Bernard */ -public class A { +public abstract class A { private Integer id; private B prop; private B[] bs; Index: res/hbm/pack/State.java =================================================================== --- res/hbm/pack/State.java (revision 0) +++ res/hbm/pack/State.java (revision 0) @@ -0,0 +1,7 @@ +package pack; + +public enum State { + + AGREED, PAYED, IN_TRANSIT, ACCEPTED, COMPLETE + +}