From 3b3c8bc9233cd869c5e0219226983e15f78791ef Mon Sep 17 00:00:00 2001 From: Emmanuel Bernard Date: Mon, 4 Oct 2010 09:45:09 +0000 Subject: [PATCH] HHH-5578 Support SpecJ's proprietary syntax Generalize the fix a bit Clean some more style issues Fix issues related to the atomicity test fixed setting proper value on property marked as many-to-one-key fixed parsing bug, now it shouldnt affect other many-to-one in the same entity fixed annotation check on many-to-one property git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@20767 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- .../org/hibernate/cfg/AnnotationBinder.java | 19 +++++++++------- .../java/org/hibernate/cfg/BinderHelper.java | 9 +++++++- .../java/org/hibernate/cfg/Configuration.java | 16 +++++++------- .../b/specjmapid/IdMapManyToOneSpecjTest.java | 22 ++++++++++++++++--- 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/core/src/main/java/org/hibernate/cfg/AnnotationBinder.java index 6ca2259f22..d0ff874b6a 100644 --- a/core/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/core/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -1417,7 +1417,6 @@ public final class AnnotationBinder { * TODO support true/false/default on the property instead of present / not present * TODO is @Column mandatory? * TODO add method support - * TODO avoid custId hardcoded */ if ( System.getProperty( "hibernate.enable_specj_proprietary_syntax" ) != null ) { if ( element.isAnnotationPresent( Id.class ) && element.isAnnotationPresent( Column.class ) ) { @@ -1433,7 +1432,7 @@ public final class AnnotationBinder { propertyAccessor, //TODO we should get the right accessor but the same as id would do mappings.getReflectionManager() ); - mappings.addPropertyAnnotatedWithMapsIdSpecj( entity, specJPropertyData, "custId" ); + mappings.addPropertyAnnotatedWithMapsIdSpecj( entity, specJPropertyData, element.toString() ); } } } @@ -2650,7 +2649,8 @@ public final class AnnotationBinder { } } - //Make sure that JPA1 key-many-to-one columns are read only too + //Make sure that JPA1 key-many-to-one columns are read only tooj + boolean hasSpecjManyToOne=false; if ( System.getProperty( "hibernate.enable_specj_proprietary_syntax" ) != null ) { String columnName = ""; for ( XProperty prop : inferredData.getDeclaringClass() @@ -2659,13 +2659,12 @@ public final class AnnotationBinder { columnName = prop.getAnnotation( Column.class ).name(); } - final JoinColumn joinColumn = prop.getAnnotation( JoinColumn.class ); - if ( prop.isAnnotationPresent( ManyToOne.class ) && joinColumn != null + final JoinColumn joinColumn = property.getAnnotation( JoinColumn.class ); + if ( property.isAnnotationPresent( ManyToOne.class ) && joinColumn != null && !joinColumn.name().isEmpty() && joinColumn.name().equals( columnName ) - && !prop.isAnnotationPresent( MapsId.class ) ) - - { + && !property.isAnnotationPresent( MapsId.class ) ) { + hasSpecjManyToOne = true; for ( Ejb3JoinColumn column : columns ) { column.setInsertable( false ); column.setUpdatable( false ); @@ -2710,6 +2709,10 @@ public final class AnnotationBinder { propertyBinder.setInsertable( false ); propertyBinder.setUpdatable( false ); } + else if (hasSpecjManyToOne) { + propertyBinder.setInsertable( false ); + propertyBinder.setUpdatable( false ); + } else { propertyBinder.setInsertable( columns[0].isInsertable() ); propertyBinder.setUpdatable( columns[0].isUpdatable() ); diff --git a/core/src/main/java/org/hibernate/cfg/BinderHelper.java b/core/src/main/java/org/hibernate/cfg/BinderHelper.java index 0e527da74d..87ccb4fa63 100644 --- a/core/src/main/java/org/hibernate/cfg/BinderHelper.java +++ b/core/src/main/java/org/hibernate/cfg/BinderHelper.java @@ -681,7 +681,14 @@ public class BinderHelper { throw new AssertionFailure( "PersistentClass name cannot be converted into a Class", e); } if ( propertyHolder.isInIdClass() ) { - return mappings.getPropertyAnnotatedWithIdAndToOne( persistentXClass, propertyName ); + PropertyData pd = mappings.getPropertyAnnotatedWithIdAndToOne( persistentXClass, propertyName ); + if ( pd == null ) { + String propertyPath = isId ? "" : propertyName; + return mappings.getPropertyAnnotatedWithMapsId( persistentXClass, propertyPath ); + } + else { + return pd; + } } else { String propertyPath = isId ? "" : propertyName; diff --git a/core/src/main/java/org/hibernate/cfg/Configuration.java b/core/src/main/java/org/hibernate/cfg/Configuration.java index e0b6202fe2..d954f9239a 100644 --- a/core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/core/src/main/java/org/hibernate/cfg/Configuration.java @@ -3594,15 +3594,15 @@ public class Configuration implements Serializable { } map.put( property.getProperty().getAnnotation( MapsId.class ).value(), property ); } - + public void addPropertyAnnotatedWithMapsIdSpecj(XClass entityType, PropertyData property, String mapsIdValue) { - Map map = propertiesAnnotatedWithMapsId.get( entityType ); - if ( map == null ) { - map = new HashMap(); - propertiesAnnotatedWithMapsId.put( entityType, map ); - } - map.put( mapsIdValue, property ); - } + Map map = propertiesAnnotatedWithMapsId.get( entityType ); + if ( map == null ) { + map = new HashMap(); + propertiesAnnotatedWithMapsId.put( entityType, map ); + } + map.put( mapsIdValue, property ); + } public PropertyData getPropertyAnnotatedWithIdAndToOne(XClass entityType, String propertyName) { final Map map = propertiesAnnotatedWithIdAndToOne.get( entityType ); diff --git a/testsuite/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/b/specjmapid/IdMapManyToOneSpecjTest.java b/testsuite/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/b/specjmapid/IdMapManyToOneSpecjTest.java index 47c8dd7383..23dce6fb29 100644 --- a/testsuite/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/b/specjmapid/IdMapManyToOneSpecjTest.java +++ b/testsuite/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/b/specjmapid/IdMapManyToOneSpecjTest.java @@ -43,6 +43,7 @@ public class IdMapManyToOneSpecjTest extends TestCase { public void testComplexIdClass() { + Session s = openSession(); Transaction tx = s.beginTransaction(); @@ -79,16 +80,17 @@ public class IdMapManyToOneSpecjTest extends TestCase { c1.addInventory( house, 100, new BigDecimal( 50000 ) ); s.merge( c1 ); - s.flush(); - s.clear(); + tx.commit(); + + tx = s.beginTransaction(); Customer c12 = ( Customer ) s.createQuery( "select c from Customer c" ).uniqueResult(); -// c12.getBalance(); List inventory = c12.getInventories(); assertEquals( 2, inventory.size() ); assertEquals( 10, inventory.get( 0 ).getQuantity() ); + assertEquals( "2", inventory.get(1).getVehicle().getId()); Item house2 = new Item(); @@ -112,6 +114,20 @@ public class IdMapManyToOneSpecjTest extends TestCase { .uniqueResult(); assertEquals( 3, c13.getInventories().size() ); + + + Customer customer2 = new Customer( + "foo2", "bar2", "contact12", "1002", new BigDecimal( 10002 ), new BigDecimal( 10002 ), new BigDecimal( 1000 )); + customer2.setId(2); + s.persist(customer2); + + customer2.addInventory(boat, 10, new BigDecimal(400)); + customer2.addInventory(house2, 3, new BigDecimal(4000)); + s.merge(customer2); + + Customer c23 = ( Customer ) s.createQuery( "select c from Customer c where c.id = 2" ).uniqueResult(); + assertEquals( 2, c23.getInventories().size() ); + tx.rollback(); s.close(); }