From 282463c2e83d9908bc257d492b5b0fdc27b71487 Mon Sep 17 00:00:00 2001 From: Robin Bygrave Date: Fri, 11 Dec 2015 10:23:34 +1300 Subject: [PATCH] #247 - @AttributeOverride at class level not read - was: @AttributeOverride annotation does not seem to work (Play 2.2.0 - ebean 3.2.2) --- .../server/deploy/parse/AnnotationClass.java | 40 +++++++++++++++++++ .../server/deploy/parse/AnnotationFields.java | 27 ------------- .../server/deploy/parse/AnnotationParser.java | 29 ++++++++++++++ .../server/deploy/parse/ReadAnnotations.java | 2 + .../avaje/tests/model/basic/first/Second.java | 3 ++ .../tests/model/basic/first/SuperSecond.java | 9 +++++ .../model/basic/first/TestFirstSecond.java | 5 +-- 7 files changed, 85 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationClass.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationClass.java index 1be877fbd..0e3e15ed4 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationClass.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationClass.java @@ -1,5 +1,7 @@ package com.avaje.ebeaninternal.server.deploy.parse; +import javax.persistence.AttributeOverride; +import javax.persistence.Column; import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.NamedQueries; @@ -26,22 +28,60 @@ import com.avaje.ebeaninternal.server.deploy.CompoundUniqueConstraint; import com.avaje.ebeaninternal.server.deploy.DeployNamedQuery; import com.avaje.ebeaninternal.server.deploy.DeployNamedUpdate; import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Read the class level deployment annotations. */ public class AnnotationClass extends AnnotationParser { + private static final Logger logger = LoggerFactory.getLogger(AnnotationClass.class); + private final String asOfViewSuffix; private final String versionsBetweenSuffix; + /** + * Create for normal early parse of class level annotations. + */ public AnnotationClass(DeployBeanInfo info, boolean validationAnnotations, String asOfViewSuffix, String versionsBetweenSuffix) { super(info, validationAnnotations); this.asOfViewSuffix = asOfViewSuffix; this.versionsBetweenSuffix = versionsBetweenSuffix; } + /** + * Create to parse AttributeOverride annotations which is run last + * after all the properties/fields have been parsed fully. + */ + public AnnotationClass(DeployBeanInfo info) { + super(info, false); + this.asOfViewSuffix = null; + this.versionsBetweenSuffix = null; + } + + /** + * Parse any AttributeOverride set on the class. + */ + public void parseAttributeOverride() { + + Class cls = descriptor.getBeanType(); + AttributeOverride override = cls.getAnnotation(AttributeOverride.class); + if (override != null) { + String propertyName = override.name(); + Column column = override.column(); + if (column != null) { + DeployBeanProperty beanProperty = descriptor.getBeanProperty(propertyName); + if (beanProperty == null) { + logger.error("AttributeOverride property [" + propertyName + "] not found on " + descriptor.getFullName()); + } else { + readColumn(column, beanProperty); + } + } + } + } + /** * Read the class level deployment annotations. */ diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java index 93f82c994..bb2777181 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationFields.java @@ -460,32 +460,5 @@ public class AnnotationFields extends AnnotationParser { } } - private void readColumn(Column columnAnn, DeployBeanProperty prop) { - - if (!isEmpty(columnAnn.name())) { - String dbColumn = databasePlatform.convertQuotedIdentifiers(columnAnn.name()); - prop.setDbColumn(dbColumn); - } - - prop.setDbInsertable(columnAnn.insertable()); - prop.setDbUpdateable(columnAnn.updatable()); - prop.setNullable(columnAnn.nullable()); - prop.setUnique(columnAnn.unique()); - if (columnAnn.precision() > 0) { - prop.setDbLength(columnAnn.precision()); - } else if (columnAnn.length() != 255) { - // set default 255 on DbTypeMap - prop.setDbLength(columnAnn.length()); - } - prop.setDbScale(columnAnn.scale()); - prop.setDbColumnDefn(columnAnn.columnDefinition()); - - String baseTable = descriptor.getBaseTable(); - String tableName = columnAnn.table(); - if (!"".equals(tableName) && !tableName.equalsIgnoreCase(baseTable)) { - // its on a secondary table... - prop.setSecondaryTable(tableName); - } - } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationParser.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationParser.java index ed71b2e93..031681a5b 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationParser.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/AnnotationParser.java @@ -5,9 +5,11 @@ import java.util.HashMap; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.CascadeType; +import javax.persistence.Column; import com.avaje.ebeaninternal.server.deploy.BeanCascadeInfo; import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanDescriptor; +import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanProperty; import com.avaje.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocOne; /** @@ -66,4 +68,31 @@ public abstract class AnnotationParser extends AnnotationBase { } + protected void readColumn(Column columnAnn, DeployBeanProperty prop) { + + if (!isEmpty(columnAnn.name())) { + String dbColumn = databasePlatform.convertQuotedIdentifiers(columnAnn.name()); + prop.setDbColumn(dbColumn); + } + + prop.setDbInsertable(columnAnn.insertable()); + prop.setDbUpdateable(columnAnn.updatable()); + prop.setNullable(columnAnn.nullable()); + prop.setUnique(columnAnn.unique()); + if (columnAnn.precision() > 0) { + prop.setDbLength(columnAnn.precision()); + } else if (columnAnn.length() != 255) { + // set default 255 on DbTypeMap + prop.setDbLength(columnAnn.length()); + } + prop.setDbScale(columnAnn.scale()); + prop.setDbColumnDefn(columnAnn.columnDefinition()); + + String baseTable = descriptor.getBaseTable(); + String tableName = columnAnn.table(); + if (!"".equals(tableName) && !tableName.equalsIgnoreCase(baseTable)) { + // its on a secondary table... + prop.setSecondaryTable(tableName); + } + } } diff --git a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/ReadAnnotations.java b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/ReadAnnotations.java index e1bc81db2..49b829abf 100644 --- a/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/ReadAnnotations.java +++ b/src/main/java/com/avaje/ebeaninternal/server/deploy/parse/ReadAnnotations.java @@ -79,6 +79,8 @@ public class ReadAnnotations { // dependent on field level annotations new AnnotationSql(info, javaxValidationAnnotations).parse(); + new AnnotationClass(info).parseAttributeOverride(); + } catch (RuntimeException e) { throw new RuntimeException("Error reading annotations for " + info, e); } diff --git a/src/test/java/com/avaje/tests/model/basic/first/Second.java b/src/test/java/com/avaje/tests/model/basic/first/Second.java index 585011585..4c5e808b8 100644 --- a/src/test/java/com/avaje/tests/model/basic/first/Second.java +++ b/src/test/java/com/avaje/tests/model/basic/first/Second.java @@ -1,9 +1,12 @@ package com.avaje.tests.model.basic.first; +import javax.persistence.AttributeOverride; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; +@AttributeOverride(name="name", column=@Column(name = "mod_name")) @Entity @Table(name = "f_second") public class Second extends SuperSecond { diff --git a/src/test/java/com/avaje/tests/model/basic/first/SuperSecond.java b/src/test/java/com/avaje/tests/model/basic/first/SuperSecond.java index c3d7073bd..a82a7a4d2 100644 --- a/src/test/java/com/avaje/tests/model/basic/first/SuperSecond.java +++ b/src/test/java/com/avaje/tests/model/basic/first/SuperSecond.java @@ -8,6 +8,8 @@ import javax.persistence.OneToOne; @MappedSuperclass public abstract class SuperSecond { + protected String name; + @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE }) @JoinColumn(name = "first") protected First first; @@ -20,4 +22,11 @@ public abstract class SuperSecond { this.first = first; } + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } diff --git a/src/test/java/com/avaje/tests/model/basic/first/TestFirstSecond.java b/src/test/java/com/avaje/tests/model/basic/first/TestFirstSecond.java index 66de5b704..3a4c6bd68 100644 --- a/src/test/java/com/avaje/tests/model/basic/first/TestFirstSecond.java +++ b/src/test/java/com/avaje/tests/model/basic/first/TestFirstSecond.java @@ -15,7 +15,8 @@ public class TestFirstSecond extends BaseTestCase { Ebean.save(first); Second second = new Second(); - second.setTitle("John"); + second.setName("Jim"); + second.setTitle("Sir"); second.setFirst(first); Ebean.save(second); @@ -23,7 +24,5 @@ public class TestFirstSecond extends BaseTestCase { second.getFirst().setName("changed"); Ebean.save(second); Ebean.save(first); - - } }