joinColumns = annotationJoinColumns(prop);
+ if (!joinColumns.isEmpty()) {
prop.getTableJoin().addJoinColumn(util, true, joinColumns, beanTable);
}
@@ -194,7 +194,7 @@ class AnnotationAssocManys extends AnnotationParser {
if (!elementCollection.targetClass().equals(void.class)) {
prop.setTargetType(elementCollection.targetClass());
}
- Column column = get(prop, Column.class);
+ Column column = prop.getMetaAnnotation(Column.class);
if (column != null) {
prop.setDbColumn(column.name());
prop.setDbLength(column.length());
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java
index b2971413b..8d4d178f1 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationAssocOnes.java
@@ -82,7 +82,7 @@ public class AnnotationAssocOnes extends AnnotationParser {
prop.setId();
prop.setNullable(false);
}
- Column column = get(prop, Column.class);
+ Column column = prop.getMetaAnnotation(Column.class);
if (column != null && !isEmpty(column.name())) {
// have this in for AssocOnes used on
// Sql based beans...
@@ -100,7 +100,7 @@ public class AnnotationAssocOnes extends AnnotationParser {
prop.setForeignKey(new PropertyForeignKey(dbForeignKey));
}
- Where where = get(prop, Where.class);
+ Where where = prop.getMetaAnnotationWhere(platform);
if (where != null) {
// not expecting this to be used on assoc one properties
prop.setExtraWhere(where.clause());
@@ -131,12 +131,11 @@ public class AnnotationAssocOnes extends AnnotationParser {
// check for manually defined joins
BeanTable beanTable = prop.getBeanTable();
- for (JoinColumn joinColumn : getAll(prop, JoinColumn.class)) {
+ for (JoinColumn joinColumn : annotationJoinColumns(prop)) {
setFromJoinColumn(prop, beanTable, joinColumn);
checkForNoConstraint(prop, joinColumn);
}
-
JoinTable joinTable = get(prop, JoinTable.class);
if (joinTable != null) {
for (JoinColumn joinColumn : joinTable.joinColumns()) {
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationBase.java b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationBase.java
index 84fda2072..4cf692468 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationBase.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationBase.java
@@ -1,16 +1,27 @@
package io.ebeaninternal.server.deploy.parse;
+import io.ebean.annotation.Aggregation;
+import io.ebean.annotation.Avg;
+import io.ebean.annotation.DbMigration;
+import io.ebean.annotation.Index;
+import io.ebean.annotation.Indices;
+import io.ebean.annotation.Max;
+import io.ebean.annotation.Min;
import io.ebean.annotation.Platform;
+import io.ebean.annotation.Sum;
import io.ebean.config.NamingConvention;
import io.ebean.config.dbplatform.DatabasePlatform;
import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
+import javax.persistence.AttributeOverride;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
-import java.lang.reflect.Method;
+import java.util.Collections;
import java.util.Set;
/**
@@ -41,7 +52,7 @@ import java.util.Set;
abstract class AnnotationBase {
final DatabasePlatform databasePlatform;
- private final Platform platform;
+ protected final Platform platform;
final NamingConvention namingConvention;
final DeployUtil util;
@@ -64,68 +75,43 @@ abstract class AnnotationBase {
return s == null || s.trim().isEmpty();
}
- /**
- * Return the annotation for the property.
- *
- * Looks first at the field and then at the getter method. It searches for meta-annotations, but not
- * recursively in the class hierarchy.
- *
- *
- * If a repeatable annotation class is specified and the annotation is platform
- * specific then the platform specific annotation is returned. Otherwise the first annotation
- * is returned. Note that you need no longer handle "java 1.6 repeatable containers"
- * like {@link JoinColumn} / {@link JoinColumns} yourself.
- *
- *
- */
T get(DeployBeanProperty prop, Class annClass) {
- T a = null;
- Field field = prop.getField();
- if (field != null) {
- a = AnnotationUtil.findAnnotation(field, annClass, platform);
- }
- if (a == null) {
- Method method = prop.getReadMethod();
- if (method != null) {
- a = AnnotationUtil.findAnnotation(method, annClass, platform);
- }
- }
- return a;
+ return AnnotationUtil.get(prop.getField(), annClass);
}
- /**
- * Return all annotations for this property. Annotations are not filtered by platfrom and you'll get
- * really all annotations that are directly, indirectly or meta-present.
- */
- Set getAll(DeployBeanProperty prop, Class annClass) {
- Set ret = null;
- Field field = prop.getField();
- if (field != null) {
- ret = AnnotationUtil.findAnnotations(field, annClass);
- }
- Method method = prop.getReadMethod();
- if (method != null) {
- if (ret != null) {
- ret.addAll(AnnotationUtil.findAnnotations(method, annClass));
- } else {
- ret = AnnotationUtil.findAnnotations(method, annClass);
- }
- }
- return ret;
+ boolean has(DeployBeanProperty prop, Class annClass) {
+ return AnnotationUtil.has(prop.getField(), annClass);
}
- /**
- * Return the annotation for the property.
- *
- * Looks first at the field and then at the getter method. then at class level.
- * (This is used for SequenceGenerator e.g.)
- *
- */
- T find(DeployBeanProperty prop, Class annClass) {
- T a = get(prop, annClass);
- if (a == null) {
- a = AnnotationUtil.findAnnotation(prop.getOwningType(), annClass, platform);
+ Set annotationJoinColumns(DeployBeanProperty prop) {
+ return AnnotationFind.joinColumns(prop.getField());
+ }
+
+ Set annotationAttributeOverrides(DeployBeanProperty prop) {
+ return AnnotationFind.attributeOverrides(prop.getField());
+ }
+
+ Set annotationIndexes(DeployBeanProperty prop) {
+ return AnnotationFind.indexes(prop.getField());
+ }
+
+ Set annotationDbMigrations(DeployBeanProperty prop) {
+ return AnnotationFind.dbMigrations(prop.getField());
+ }
+
+ Set annotationClassIndexes(Class> cls) {
+ Set result = AnnotationUtil.typeGetAll(cls, Index.class);
+ for (Indices index : AnnotationUtil.typeGetAll(cls, Indices.class)) {
+ Collections.addAll(result, index.value());
}
- return a;
+ return result;
+ }
+
+ Set annotationClassNamedQuery(Class> cls) {
+ Set result = AnnotationUtil.typeGetAll(cls, NamedQuery.class);
+ for (NamedQueries queries : AnnotationUtil.typeGetAll(cls, NamedQueries.class)) {
+ Collections.addAll(result, queries.value());
+ }
+ return result;
}
}
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java
index b12c030aa..8985fb4ac 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationClass.java
@@ -31,8 +31,7 @@ import javax.persistence.NamedQuery;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
-import static io.ebean.util.AnnotationUtil.findAnnotationRecursive;
-import static io.ebean.util.AnnotationUtil.findAnnotationsRecursive;
+import static io.ebean.util.AnnotationUtil.typeGet;
/**
* Read the class level deployment annotations.
@@ -62,9 +61,8 @@ public class AnnotationClass extends AnnotationParser {
* Parse any AttributeOverride set on the class.
*/
void parseAttributeOverride() {
-
Class> cls = descriptor.getBeanType();
- AttributeOverride override = findAnnotationRecursive(cls, AttributeOverride.class);
+ AttributeOverride override = typeGet(cls, AttributeOverride.class);
if (override != null) {
String propertyName = override.name();
Column column = override.column();
@@ -104,16 +102,15 @@ public class AnnotationClass extends AnnotationParser {
}
private void read(Class> cls) {
-
// maybe doc store only so check for this before @Entity
- DocStore docStore = findAnnotationRecursive(cls, DocStore.class);
+ DocStore docStore = typeGet(cls, DocStore.class);
if (docStore != null) {
descriptor.readDocStore(docStore);
descriptor.setEntityType(EntityType.DOC);
descriptor.setName(cls.getSimpleName());
}
- Entity entity = findAnnotationRecursive(cls, Entity.class);
+ Entity entity = typeGet(cls, Entity.class);
if (entity != null) {
descriptor.setEntityType(EntityType.ORM);
if (entity.name().isEmpty()) {
@@ -123,37 +120,37 @@ public class AnnotationClass extends AnnotationParser {
}
}
- Identity identity = findAnnotationRecursive(cls, Identity.class);
+ Identity identity = typeGet(cls, Identity.class);
if (identity != null) {
descriptor.setIdentityMode(identity);
}
- IdClass idClass = findAnnotationRecursive(cls, IdClass.class);
+ IdClass idClass = typeGet(cls, IdClass.class);
if (idClass != null) {
descriptor.setIdClass(idClass.value());
}
- Embeddable embeddable = findAnnotationRecursive(cls, Embeddable.class);
+ Embeddable embeddable = typeGet(cls, Embeddable.class);
if (embeddable != null) {
descriptor.setEntityType(EntityType.EMBEDDED);
descriptor.setName("Embeddable:" + cls.getSimpleName());
}
- for (Index index : findAnnotationsRecursive(cls, Index.class)) {
+ for (Index index : annotationClassIndexes(cls)) {
descriptor.addIndex(new IndexDefinition(convertColumnNames(index.columnNames()), index.name(),
index.unique(), index.platforms(), index.concurrent(), index.definition()));
}
- UniqueConstraint uc = findAnnotationRecursive(cls, UniqueConstraint.class);
+ UniqueConstraint uc = typeGet(cls, UniqueConstraint.class);
if (uc != null) {
descriptor.addIndex(new IndexDefinition(convertColumnNames(uc.columnNames())));
}
- View view = findAnnotationRecursive(cls, View.class);
+ View view = typeGet(cls, View.class);
if (view != null) {
descriptor.setView(view.name(), view.dependentTables());
}
- Table table = findAnnotationRecursive(cls, Table.class);
+ Table table = typeGet(cls, Table.class);
if (table != null) {
UniqueConstraint[] uniqueConstraints = table.uniqueConstraints();
for (UniqueConstraint c : uniqueConstraints) {
@@ -161,54 +158,54 @@ public class AnnotationClass extends AnnotationParser {
}
}
- StorageEngine storage = findAnnotationRecursive(cls, StorageEngine.class);
+ StorageEngine storage = typeGet(cls, StorageEngine.class);
if (storage != null) {
descriptor.setStorageEngine(storage.value());
}
- DbPartition partition = findAnnotationRecursive(cls, DbPartition.class);
+ DbPartition partition = typeGet(cls, DbPartition.class);
if (partition != null) {
descriptor.setPartitionMeta(new PartitionMeta(partition.mode(), partition.property()));
}
- Draftable draftable = findAnnotationRecursive(cls, Draftable.class);
+ Draftable draftable = typeGet(cls, Draftable.class);
if (draftable != null) {
descriptor.setDraftable();
}
- DraftableElement draftableElement = findAnnotationRecursive(cls, DraftableElement.class);
+ DraftableElement draftableElement = typeGet(cls, DraftableElement.class);
if (draftableElement != null) {
descriptor.setDraftableElement();
}
- ReadAudit readAudit = findAnnotationRecursive(cls, ReadAudit.class);
+ ReadAudit readAudit = typeGet(cls, ReadAudit.class);
if (readAudit != null) {
descriptor.setReadAuditing();
}
- History history = findAnnotationRecursive(cls, History.class);
+ History history = typeGet(cls, History.class);
if (history != null) {
descriptor.setHistorySupport();
}
- DbComment comment = findAnnotationRecursive(cls, DbComment.class);
+ DbComment comment = typeGet(cls, DbComment.class);
if (comment != null) {
descriptor.setDbComment(comment.value());
}
if (!disableL2Cache) {
- Cache cache = findAnnotationRecursive(cls, Cache.class);
+ Cache cache = typeGet(cls, Cache.class);
if (cache != null) {
descriptor.setCache(cache);
} else {
- InvalidateQueryCache invalidateQueryCache = findAnnotationRecursive(cls, InvalidateQueryCache.class);
+ InvalidateQueryCache invalidateQueryCache = typeGet(cls, InvalidateQueryCache.class);
if (invalidateQueryCache != null) {
descriptor.setInvalidateQueryCache(invalidateQueryCache.region());
}
}
}
- for (NamedQuery namedQuery : findAnnotationsRecursive(cls, NamedQuery.class)) {
+ for (NamedQuery namedQuery : annotationClassNamedQuery(cls)) {
descriptor.addNamedQuery(namedQuery.name(), namedQuery.query());
}
}
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFields.java b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFields.java
index 14a35ac31..195ff6610 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFields.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFields.java
@@ -106,8 +106,8 @@ public class AnnotationFields extends AnnotationParser {
*/
@Override
public void parse() {
-
for (DeployBeanProperty prop : descriptor.propertiesAll()) {
+ prop.initMetaAnnotations(readConfig.getMetaAnnotations());
if (prop instanceof DeployBeanPropertyAssoc>) {
readAssocOne((DeployBeanPropertyAssoc>) prop);
} else {
@@ -123,13 +123,11 @@ public class AnnotationFields extends AnnotationParser {
readJsonAnnotations(prop);
- Id id = get(prop, Id.class);
- if (id != null) {
+ if (has(prop, Id.class)) {
readIdAssocOne(prop);
}
- EmbeddedId embeddedId = get(prop, EmbeddedId.class);
- if (embeddedId != null) {
+ if (has(prop, EmbeddedId.class)) {
prop.setId();
prop.setNullable(false);
prop.setEmbedded();
@@ -140,7 +138,7 @@ public class AnnotationFields extends AnnotationParser {
if (docEmbedded != null) {
prop.setDocStoreEmbedded(docEmbedded.doc());
if (descriptor.isDocStoreOnly()) {
- if (get(prop, ManyToOne.class) == null) {
+ if (has(prop, ManyToOne.class)) {
prop.setEmbedded();
prop.setDbInsertable(true);
prop.setDbUpdateable(true);
@@ -155,20 +153,20 @@ public class AnnotationFields extends AnnotationParser {
readEmbeddedAttributeOverrides((DeployBeanPropertyAssocOne>) prop);
}
- Formula formula = get(prop, Formula.class);
+ Formula formula = prop.getMetaAnnotationFormula(platform);
if (formula != null) {
prop.setSqlFormula(formula.select(), formula.join());
}
initWhoProperties(prop);
- readDbMigration(prop);
+ initDbMigration(prop);
}
private void initWhoProperties(DeployBeanProperty prop) {
- if (get(prop, WhoModified.class) != null) {
+ if (has(prop, WhoModified.class)) {
generatedPropFactory.setWhoModified(prop);
}
- if (get(prop, WhoCreated.class) != null) {
+ if (has(prop, WhoCreated.class)) {
generatedPropFactory.setWhoCreated(prop);
}
}
@@ -188,7 +186,7 @@ public class AnnotationFields extends AnnotationParser {
prop.setDbInsertable(true);
prop.setDbUpdateable(true);
- Column column = get(prop, Column.class);
+ Column column = prop.getMetaAnnotation(Column.class);
if (column != null) {
readColumn(column, prop);
}
@@ -200,6 +198,32 @@ public class AnnotationFields extends AnnotationParser {
prop.setDbColumn(namingConvention.getColumnFromProperty(beanType, prop.getName()));
}
+ initIdentity(prop);
+ initTenantId(prop);
+ initDbJson(prop);
+ initFormula(prop);
+ initVersion(prop);
+ initWhen(prop);
+ initWhoProperties(prop);
+ initDbMigration(prop);
+
+ // Want to process last so we can use with @Formula
+ if (has(prop, Transient.class)) {
+ // it is not a persistent property.
+ prop.setDbRead(false);
+ prop.setDbInsertable(false);
+ prop.setDbUpdateable(false);
+ prop.setTransient();
+ }
+
+ initEncrypt(prop);
+
+ for (Index index : annotationIndexes(prop)) {
+ addIndex(prop, index);
+ }
+ }
+
+ private void initIdentity(DeployBeanProperty prop) {
Id id = get(prop, Id.class);
GeneratedValue gen = get(prop, GeneratedValue.class);
if (gen != null) {
@@ -219,7 +243,7 @@ public class AnnotationFields extends AnnotationParser {
if (temporal != null) {
readTemporal(temporal, prop);
- } else if (get(prop, Lob.class) != null) {
+ } else if (has(prop, Lob.class)) {
util.setLobType(prop);
}
@@ -228,53 +252,58 @@ public class AnnotationFields extends AnnotationParser {
prop.setDbLength(length.value());
}
- io.ebean.annotation.NotNull nonNull = get(prop, io.ebean.annotation.NotNull.class);
- if (nonNull != null) {
+ if (has(prop, io.ebean.annotation.NotNull.class)) {
+ prop.setNullable(false);
+ }
+ }
+
+ private void initValidation(DeployBeanProperty prop) {
+ NotNull notNull = get(prop, NotNull.class);
+ if (notNull != null && isEbeanValidationGroups(notNull.groups())) {
+ // Not null on all validation groups so enable
+ // DDL generation of Not Null Constraint
prop.setNullable(false);
}
- if (validationAnnotations) {
- NotNull notNull = get(prop, NotNull.class);
- if (notNull != null && isEbeanValidationGroups(notNull.groups())) {
- // Not null on all validation groups so enable
- // DDL generation of Not Null Constraint
- prop.setNullable(false);
+ if (!prop.isLob()) {
+ // take the max size of all @Size annotations
+ int maxSize = -1;
+ for (Size size : prop.getMetaAnnotationSize()) {
+ if (size.max() < Integer.MAX_VALUE) {
+ maxSize = Math.max(maxSize, size.max());
+ }
}
-
- if (!prop.isLob()) {
- // take the max size of all @Size annotations
- int maxSize = -1;
- for (Size size : getAll(prop, Size.class)) {
- if (size.max() < Integer.MAX_VALUE) {
- maxSize = Math.max(maxSize, size.max());
- }
- }
- if (maxSize != -1) {
- prop.setDbLength(maxSize);
- }
+ if (maxSize != -1) {
+ prop.setDbLength(maxSize);
}
}
+ }
- if (get(prop, TenantId.class) != null) {
+ private void initTenantId(DeployBeanProperty prop) {
+ if (validationAnnotations) {
+ initValidation(prop);
+ }
+ if (has(prop, TenantId.class)) {
prop.setTenantId();
}
- if (get(prop, Draft.class) != null) {
+ if (has(prop, Draft.class)) {
prop.setDraft();
}
- if (get(prop, DraftOnly.class) != null) {
+ if (has(prop, DraftOnly.class)) {
prop.setDraftOnly();
}
- if (get(prop, DraftDirty.class) != null) {
+ if (has(prop, DraftDirty.class)) {
prop.setDraftDirty();
}
- if (get(prop, DraftReset.class) != null) {
+ if (has(prop, DraftReset.class)) {
prop.setDraftReset();
}
- SoftDelete softDelete = get(prop, SoftDelete.class);
- if (softDelete != null) {
+ if (has(prop, SoftDelete.class)) {
prop.setSoftDelete();
}
+ }
+ private void initDbJson(DeployBeanProperty prop) {
DbComment comment = get(prop, DbComment.class);
if (comment != null) {
prop.setDbComment(comment.value());
@@ -296,7 +325,9 @@ public class AnnotationFields extends AnnotationParser {
if (dbArray != null) {
util.setDbArray(prop, dbArray);
}
+ }
+ private void initFormula(DeployBeanProperty prop) {
DocCode docCode = get(prop, DocCode.class);
if (docCode != null) {
prop.setDocCode(docCode);
@@ -309,19 +340,19 @@ public class AnnotationFields extends AnnotationParser {
if (docProperty != null) {
prop.setDocProperty(docProperty);
}
-
- Formula formula = get(prop, Formula.class);
+ Formula formula = prop.getMetaAnnotationFormula(platform);
if (formula != null) {
prop.setSqlFormula(formula.select(), formula.join());
}
- Aggregation aggregation = get(prop, Aggregation.class);
+ final Aggregation aggregation = prop.getMetaAnnotation(Aggregation.class);
if (aggregation != null) {
prop.setAggregation(aggregation.value().replace("$1", prop.getName()));
}
+ }
- Version version = get(prop, Version.class);
- if (version != null) {
+ private void initVersion(DeployBeanProperty prop) {
+ if (has(prop, Version.class)) {
// explicitly specify a version column
prop.setVersionColumn();
generatedPropFactory.setVersion(prop);
@@ -337,35 +368,19 @@ public class AnnotationFields extends AnnotationParser {
// use the default Lob fetchType
prop.setFetchType(defaultLobFetchType);
}
+ }
- if (get(prop, WhenCreated.class) != null || get(prop, CreatedTimestamp.class) != null) {
+ private void initWhen(DeployBeanProperty prop) {
+ if (has(prop, WhenCreated.class) || has(prop, CreatedTimestamp.class)) {
generatedPropFactory.setInsertTimestamp(prop);
}
-
- if (get(prop, WhenModified.class) != null || get(prop, UpdatedTimestamp.class) != null) {
+ if (has(prop, WhenModified.class) || has(prop, UpdatedTimestamp.class)) {
generatedPropFactory.setUpdateTimestamp(prop);
}
+ }
- initWhoProperties(prop);
-
- if (get(prop, HistoryExclude.class) != null) {
- prop.setExcludedFromHistory();
- }
-
- readDbMigration(prop);
-
- // Want to process last so we can use with @Formula
- Transient t = get(prop, Transient.class);
- if (t != null) {
- // it is not a persistent property.
- prop.setDbRead(false);
- prop.setDbInsertable(false);
- prop.setDbUpdateable(false);
- prop.setTransient();
- }
-
+ private void initEncrypt(DeployBeanProperty prop) {
if (!prop.isTransient()) {
-
EncryptDeploy encryptDeploy = util.getEncryptDeploy(info.getDescriptor().getBaseTableFull(), prop.getDbColumn());
if (encryptDeploy == null || encryptDeploy.getMode() == Mode.MODE_ANNOTATION) {
Encrypted encrypted = get(prop, Encrypted.class);
@@ -376,24 +391,22 @@ public class AnnotationFields extends AnnotationParser {
setEncryption(prop, encryptDeploy.isDbEncrypt(), encryptDeploy.getDbLength());
}
}
-
- Set indices = getAll(prop, Index.class);
- for (Index index : indices) {
- addIndex(prop, index);
- }
}
private void readIdentity(Identity identity) {
descriptor.setIdentityMode(identity);
}
- private void readDbMigration(DeployBeanProperty prop) {
+ private void initDbMigration(DeployBeanProperty prop) {
+ if (has(prop, HistoryExclude.class)) {
+ prop.setExcludedFromHistory();
+ }
DbDefault dbDefault = get(prop, DbDefault.class);
if (dbDefault != null) {
prop.setDbColumnDefault(dbDefault.value());
}
- Set dbMigration = getAll(prop, DbMigration.class);
+ Set dbMigration = annotationDbMigrations(prop);
dbMigration.forEach(ann -> prop.addDbMigrationInfo(
new DbMigrationInfo(ann.preAdd(), ann.postAdd(), ann.preAlter(), ann.postAlter(), ann.platforms())));
}
@@ -445,15 +458,13 @@ public class AnnotationFields extends AnnotationParser {
prop.setJsonSerialize(jsonIgnore.serialize());
prop.setJsonDeserialize(jsonIgnore.deserialize());
}
- if (get(prop, UnmappedJson.class) != null) {
+ if (has(prop, UnmappedJson.class)) {
prop.setUnmappedJson();
}
}
private boolean hasRelationshipItem(DeployBeanProperty prop) {
- return get(prop, OneToMany.class) != null ||
- get(prop, ManyToOne.class) != null ||
- get(prop, OneToOne.class) != null;
+ return has(prop, OneToMany.class) || has(prop, ManyToOne.class) || has(prop, OneToOne.class);
}
private void setEncryption(DeployBeanProperty prop, boolean dbEncString, int dbLen) {
@@ -528,7 +539,7 @@ public class AnnotationFields extends AnnotationParser {
}
descriptor.setIdGeneratedValue();
- SequenceGenerator seq = find(prop, SequenceGenerator.class);
+ SequenceGenerator seq = get(prop, SequenceGenerator.class);
if (seq != null) {
String seqName = seq.sequenceName();
if (seqName.isEmpty()) {
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFind.java b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFind.java
new file mode 100644
index 000000000..0faf59837
--- /dev/null
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationFind.java
@@ -0,0 +1,75 @@
+package io.ebeaninternal.server.deploy.parse;
+
+import io.ebean.annotation.DbMigration;
+import io.ebean.annotation.Index;
+import io.ebean.annotation.Indices;
+
+import javax.persistence.AttributeOverride;
+import javax.persistence.AttributeOverrides;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import static io.ebean.util.AnnotationUtil.get;
+
+public class AnnotationFind {
+
+ public static Set joinColumns(Field field) {
+ final JoinColumn col = get(field, JoinColumn.class);
+ if (col != null) {
+ return Collections.singleton(col);
+ }
+ final JoinColumns cols = get(field, JoinColumns.class);
+ if (cols != null) {
+ Set result = new LinkedHashSet<>();
+ Collections.addAll(result, cols.value());
+ return result;
+ }
+ return Collections.emptySet();
+ }
+
+ public static Set attributeOverrides(Field field) {
+ final AttributeOverride ann = get(field, AttributeOverride.class);
+ if (ann != null) {
+ return Collections.singleton(ann);
+ }
+ final AttributeOverrides collection = get(field, AttributeOverrides.class);
+ if (collection != null) {
+ Set result = new LinkedHashSet<>();
+ Collections.addAll(result, collection.value());
+ return result;
+ }
+ return Collections.emptySet();
+ }
+
+ public static Set indexes(Field field) {
+ final Index ann = get(field, Index.class);
+ if (ann != null) {
+ return Collections.singleton(ann);
+ }
+ final Indices collection = get(field, Indices.class);
+ if (collection != null) {
+ Set result = new LinkedHashSet<>();
+ Collections.addAll(result, collection.value());
+ return result;
+ }
+ return Collections.emptySet();
+ }
+
+ public static Set dbMigrations(Field field) {
+ final DbMigration ann = get(field, DbMigration.class);
+ if (ann != null) {
+ return Collections.singleton(ann);
+ }
+ final DbMigration.List collection = get(field, DbMigration.List.class);
+ if (collection != null) {
+ Set result = new LinkedHashSet<>();
+ Collections.addAll(result, collection.value());
+ return result;
+ }
+ return Collections.emptySet();
+ }
+}
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationParser.java b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationParser.java
index d7ced0d5c..bb8158eb0 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationParser.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationParser.java
@@ -87,7 +87,7 @@ public abstract class AnnotationParser extends AnnotationBase {
*/
void readEmbeddedAttributeOverrides(DeployBeanPropertyAssocOne> prop) {
- Set attrOverrides = getAll(prop, AttributeOverride.class);
+ Set attrOverrides = annotationAttributeOverrides(prop);
if (!attrOverrides.isEmpty()) {
HashMap propMap = new HashMap<>(attrOverrides.size());
for (AttributeOverride attrOverride : attrOverrides) {
@@ -95,7 +95,6 @@ public abstract class AnnotationParser extends AnnotationBase {
}
prop.getDeployEmbedded().putAll(propMap);
}
-
}
void readColumn(Column columnAnn, DeployBeanProperty prop) {
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationSql.java b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationSql.java
index df9622b02..5001f2f70 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationSql.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/AnnotationSql.java
@@ -16,8 +16,7 @@ class AnnotationSql extends AnnotationParser {
@Override
public void parse() {
Class> cls = descriptor.getBeanType();
- Sql sql = AnnotationUtil.findAnnotationRecursive(cls, Sql.class);
- if (sql != null) {
+ if (AnnotationUtil.typeHas(cls, Sql.class)) {
descriptor.setEntityType(BeanDescriptor.EntityType.SQL);
}
}
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java b/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java
index bdaf79f44..e8223abd4 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/DeployCreateProperties.java
@@ -23,7 +23,6 @@ import javax.persistence.ManyToOne;
import javax.persistence.PersistenceException;
import javax.persistence.Transient;
import java.lang.reflect.Field;
-import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
@@ -53,7 +52,6 @@ public class DeployCreateProperties {
* Create the appropriate properties for a bean.
*/
public void createProperties(DeployBeanDescriptor> desc) {
-
createProperties(desc, desc.getBeanType(), 0);
desc.sortProperties();
}
@@ -89,22 +87,14 @@ public class DeployCreateProperties {
// ignore all fields on model (_$dbName)
return;
}
- boolean scalaObject = desc.isScalaObject();
try {
- Method[] declaredMethods = beanType.getDeclaredMethods();
Field[] fields = beanType.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
-
Field field = fields[i];
if (!ignoreField(field)) {
- String fieldName = getFieldName(field, beanType);
- String initFieldName = initCap(fieldName);
-
- Method getter = findGetter(field, initFieldName, declaredMethods, scalaObject);
-
- DeployBeanProperty prop = createProp(desc, field, beanType, getter);
+ DeployBeanProperty prop = createProp(desc, field, beanType);
if (prop != null) {
// set a order that gives priority to inherited properties
// push Id/EmbeddedId up and CreatedTimestamp/UpdatedTimestamp down
@@ -137,68 +127,6 @@ public class DeployCreateProperties {
}
}
- /**
- * Make the first letter of the string upper case.
- */
- private String initCap(String str) {
- if (str.length() > 1) {
- return Character.toUpperCase(str.charAt(0)) + str.substring(1);
- } else {
- // only a single char
- return str.toUpperCase();
- }
- }
-
- /**
- * Return the bean spec field name (trim of "is" from boolean types)
- */
- private String getFieldName(Field field, Class> beanType) {
-
- String name = field.getName();
-
- if ((Boolean.class.equals(field.getType()) || boolean.class.equals(field.getType()))
- && name.startsWith("is") && name.length() > 2) {
-
- // it is a boolean type field starting with "is"
- char c = name.charAt(2);
- if (Character.isUpperCase(c)) {
- String msg = "trimming off 'is' from boolean field name " + name + " in class " + beanType.getName();
- logger.info(msg);
-
- return name.substring(2);
- }
- }
- return name;
- }
-
- /**
- * Find a public non-static getter method that matches this field (according to bean-spec rules).
- */
- private Method findGetter(Field field, String initFieldName, Method[] declaredMethods, boolean scalaObject) {
-
- String methGetName = "get" + initFieldName;
- String methIsName = "is" + initFieldName;
- String scalaGet = field.getName();
-
- for (Method m : declaredMethods) {
- if ((scalaObject && m.getName().equals(scalaGet)) || m.getName().equals(methGetName)
- || m.getName().equals(methIsName)) {
-
- Class>[] params = m.getParameterTypes();
- if (params.length == 0) {
- if (field.getType().equals(m.getReturnType())) {
- int modifiers = m.getModifiers();
- if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) {
- // we find it...
- return m;
- }
- }
- }
- }
- }
- return null;
- }
-
@SuppressWarnings({"unchecked"})
private DeployBeanProperty createManyType(DeployBeanDescriptor> desc, Class> targetType, ManyType manyType) {
@@ -218,7 +146,7 @@ public class DeployCreateProperties {
Class> propertyType = field.getType();
- ManyToOne manyToOne = AnnotationUtil.findAnnotation(field, ManyToOne.class);
+ ManyToOne manyToOne = AnnotationUtil.get(field, ManyToOne.class);
if (manyToOne != null) {
Class> tt = manyToOne.targetEntity();
if (!tt.equals(void.class)) {
@@ -235,8 +163,7 @@ public class DeployCreateProperties {
// List, Set or Map based object
Class> targetType = determineTargetType(field);
if (targetType == null) {
- Transient transAnnotation = AnnotationUtil.findAnnotation(field, Transient.class);
- if (transAnnotation != null) {
+ if (AnnotationUtil.has(field, Transient.class)) {
// not supporting this field (generic type used)
return null;
}
@@ -271,21 +198,18 @@ public class DeployCreateProperties {
* Return true if the field has one of the special mappings.
*/
private boolean isSpecialScalarType(Field field) {
- return (AnnotationUtil.findAnnotation(field, DbJson.class) != null)
- || (AnnotationUtil.findAnnotation(field, DbJsonB.class) != null)
- || (AnnotationUtil.findAnnotation(field, DbArray.class) != null)
- || (AnnotationUtil.findAnnotation(field, DbMap.class) != null)
- || (AnnotationUtil.findAnnotation(field, UnmappedJson.class) != null);
+ return (AnnotationUtil.has(field, DbJson.class))
+ || (AnnotationUtil.has(field, DbJsonB.class))
+ || (AnnotationUtil.has(field, DbArray.class))
+ || (AnnotationUtil.has(field, DbMap.class))
+ || (AnnotationUtil.has(field, UnmappedJson.class));
}
private boolean isTransientField(Field field) {
-
- Transient t = AnnotationUtil.findAnnotation(field, Transient.class);
- return (t != null);
+ return AnnotationUtil.has(field, Transient.class);
}
- private DeployBeanProperty createProp(DeployBeanDescriptor> desc, Field field, Class> beanType, Method getter) {
-
+ private DeployBeanProperty createProp(DeployBeanDescriptor> desc, Field field, Class> beanType) {
DeployBeanProperty prop = createProp(desc, field);
if (prop == null) {
// transient annotation on unsupported type
@@ -293,9 +217,6 @@ public class DeployCreateProperties {
} else {
prop.setOwningType(beanType);
prop.setName(field.getName());
-
- // interested in the getter for reading annotations
- prop.setReadMethod(getter);
prop.setField(field);
return prop;
}
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInherit.java b/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInherit.java
index e9252c819..fd9e4641b 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInherit.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/DeployInherit.java
@@ -8,7 +8,6 @@ import io.ebeaninternal.server.deploy.meta.DeployBeanDescriptor;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Inheritance;
-import java.lang.annotation.Annotation;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -110,11 +109,11 @@ public class DeployInherit {
info.setParent(parent);
}
- Inheritance ia = AnnotationUtil.findAnnotationRecursive(cls, Inheritance.class);
+ Inheritance ia = AnnotationUtil.typeGet(cls, Inheritance.class);
if (ia != null) {
ia.strategy();
}
- DiscriminatorColumn da = AnnotationUtil.findAnnotationRecursive(cls, DiscriminatorColumn.class);
+ DiscriminatorColumn da = AnnotationUtil.typeGet(cls, DiscriminatorColumn.class);
if (da != null) {
// lowercase the discriminator column for RawSql and JSON
info.setColumnName(da.name().toLowerCase());
@@ -124,7 +123,7 @@ public class DeployInherit {
}
if (!info.isAbstract()) {
- DiscriminatorValue dv = AnnotationUtil.findAnnotation(cls, DiscriminatorValue.class); // do not search recursive
+ DiscriminatorValue dv = AnnotationUtil.get(cls, DiscriminatorValue.class); // do not search recursive
if (dv != null) {
info.setDiscriminatorValue(dv.value());
} else {
@@ -144,17 +143,7 @@ public class DeployInherit {
}
private boolean isInheritanceClass(Class> cls) {
- while (true) {
- if (cls.equals(Object.class)) {
- return false;
- }
- Annotation a = AnnotationUtil.findAnnotationRecursive(cls, Inheritance.class);
- if (a != null) {
- return true;
- }
- // search up the inheritance heirarchy
- cls = cls.getSuperclass();
- }
+ return AnnotationUtil.typeHas(cls, Inheritance.class);
}
}
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/InitMetaJacksonAnnotation.java b/src/main/java/io/ebeaninternal/server/deploy/parse/InitMetaJacksonAnnotation.java
new file mode 100644
index 000000000..08435de62
--- /dev/null
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/InitMetaJacksonAnnotation.java
@@ -0,0 +1,8 @@
+package io.ebeaninternal.server.deploy.parse;
+
+class InitMetaJacksonAnnotation {
+
+ static void init(ReadAnnotationConfig readConfig) {
+ readConfig.addMetaAnnotation(com.fasterxml.jackson.annotation.JacksonAnnotation.class);
+ }
+}
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/InitMetaValidationAnnotation.java b/src/main/java/io/ebeaninternal/server/deploy/parse/InitMetaValidationAnnotation.java
new file mode 100644
index 000000000..9d5ac9e30
--- /dev/null
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/InitMetaValidationAnnotation.java
@@ -0,0 +1,11 @@
+package io.ebeaninternal.server.deploy.parse;
+
+import javax.validation.constraints.Size;
+
+class InitMetaValidationAnnotation {
+
+ static void init(ReadAnnotationConfig readConfig) {
+ readConfig.addMetaAnnotation(Size.class);
+ readConfig.addMetaAnnotation(Size.List.class);
+ }
+}
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotationConfig.java b/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotationConfig.java
index 32e5573a5..e1cb4530a 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotationConfig.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotationConfig.java
@@ -1,8 +1,15 @@
package io.ebeaninternal.server.deploy.parse;
+import io.ebean.annotation.Aggregation;
+import io.ebean.annotation.Formula;
+import io.ebean.annotation.Where;
import io.ebean.config.ServerConfig;
import io.ebeaninternal.server.deploy.generatedproperty.GeneratedPropertyFactory;
+import javax.persistence.Column;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* Configuration used when reading the deployment annotations.
*/
@@ -17,6 +24,8 @@ class ReadAnnotationConfig {
private final boolean jacksonAnnotations;
private final boolean idGeneratorAutomatic;
+ private final Set> metaAnnotations = new HashSet<>();
+
ReadAnnotationConfig(GeneratedPropertyFactory generatedPropFactory, String asOfViewSuffix, String versionsBetweenSuffix, ServerConfig serverConfig) {
this.generatedPropFactory = generatedPropFactory;
@@ -28,6 +37,16 @@ class ReadAnnotationConfig {
this.javaxValidationAnnotations = generatedPropFactory.getClassLoadConfig().isJavaxValidationAnnotationsPresent();
this.jacksonAnnotations = generatedPropFactory.getClassLoadConfig().isJacksonAnnotationsPresent();
+ this.metaAnnotations.add(Column.class);
+ this.metaAnnotations.add(Formula.class);
+ this.metaAnnotations.add(Formula.List.class);
+ this.metaAnnotations.add(Where.class);
+ this.metaAnnotations.add(Where.List.class);
+ this.metaAnnotations.add(Aggregation.class);
+ }
+
+ public void addMetaAnnotation(Class> annotation) {
+ metaAnnotations.add(annotation);
}
GeneratedPropertyFactory getGeneratedPropFactory() {
@@ -61,4 +80,8 @@ class ReadAnnotationConfig {
boolean isJacksonAnnotations() {
return jacksonAnnotations;
}
+
+ public Set> getMetaAnnotations() {
+ return metaAnnotations;
+ }
}
diff --git a/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotations.java b/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotations.java
index 534e9cb82..aad6f547e 100644
--- a/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotations.java
+++ b/src/main/java/io/ebeaninternal/server/deploy/parse/ReadAnnotations.java
@@ -14,6 +14,12 @@ public class ReadAnnotations {
public ReadAnnotations(GeneratedPropertyFactory generatedPropFactory, String asOfViewSuffix, String versionsBetweenSuffix, ServerConfig serverConfig) {
this.readConfig = new ReadAnnotationConfig(generatedPropFactory, asOfViewSuffix, versionsBetweenSuffix, serverConfig);
+ if (readConfig.isJavaxValidationAnnotations()) {
+ InitMetaValidationAnnotation.init(readConfig);
+ }
+ if (readConfig.isJacksonAnnotations()) {
+ InitMetaJacksonAnnotation.init(readConfig);
+ }
}
/**
diff --git a/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java b/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java
index bada29fe1..521721553 100644
--- a/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java
+++ b/src/main/java/io/ebeaninternal/server/type/DefaultTypeManager.java
@@ -459,7 +459,7 @@ public final class DefaultTypeManager implements TypeManager {
* are annotated with the @JacksonAnnotation meta annotation. So detection is easy.
*/
private boolean checkJacksonAnnotations(DeployBeanProperty prop) {
- return AnnotationUtil.findAnnotation(prop.getField(), com.fasterxml.jackson.annotation.JacksonAnnotation.class) != null;
+ return prop.getMetaAnnotation(com.fasterxml.jackson.annotation.JacksonAnnotation.class) != null;
}
private DocPropertyType getDocType(Type genericType) {
@@ -606,7 +606,7 @@ public final class DefaultTypeManager implements TypeManager {
Field[] fields = enumType.getDeclaredFields();
for (Field field : fields) {
- EnumValue enumValue = AnnotationUtil.findAnnotation(field, EnumValue.class);
+ EnumValue enumValue = AnnotationUtil.get(field, EnumValue.class);
if (enumValue != null) {
nameValueMap.put(field.getName(), enumValue.value());
if (integerType && !isIntegerType(enumValue.value())) {
@@ -680,7 +680,7 @@ public final class DefaultTypeManager implements TypeManager {
Method[] methods = enumType.getMethods();
for (Method method : methods) {
- DbEnumValue dbValue = AnnotationUtil.findAnnotation(method, DbEnumValue.class);
+ DbEnumValue dbValue = AnnotationUtil.get(method, DbEnumValue.class);
if (dbValue != null) {
boolean integerValues = DbEnumType.INTEGER == dbValue.storage();
return createEnumScalarTypeDbValue(enumType, method, integerValues, dbValue.length());
diff --git a/src/test/java/org/tests/basic/TestAnnotationBase.java b/src/test/java/org/tests/basic/TestAnnotationBase.java
index f84ec99ab..573199ce2 100644
--- a/src/test/java/org/tests/basic/TestAnnotationBase.java
+++ b/src/test/java/org/tests/basic/TestAnnotationBase.java
@@ -1,15 +1,18 @@
package org.tests.basic;
import io.ebean.BaseTestCase;
+import io.ebean.annotation.Index;
import io.ebean.annotation.Platform;
import io.ebean.annotation.Where;
-import io.ebean.util.AnnotationUtil;
import io.ebeaninternal.server.deploy.BeanDescriptor;
import io.ebeaninternal.server.deploy.BeanProperty;
+import io.ebeaninternal.server.deploy.IndexDefinition;
+import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
import org.junit.Test;
import org.tests.model.basic.ValidationGroupSomething;
import javax.persistence.Entity;
+import javax.persistence.MappedSuperclass;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.lang.annotation.ElementType;
@@ -17,6 +20,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
+import java.util.HashSet;
+import java.util.Set;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -25,6 +30,13 @@ import static org.junit.Assert.assertTrue;
public class TestAnnotationBase extends BaseTestCase {
+ private final Set> metaAnnotationsFilter = new HashSet<>();
+
+ public TestAnnotationBase() {
+ metaAnnotationsFilter.add(Where.class);
+ metaAnnotationsFilter.add(Where.List.class);
+ }
+
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Where(clause = "SELECT 'mysql' from 1", platforms = Platform.MYSQL)
@@ -34,8 +46,16 @@ public class TestAnnotationBase extends BaseTestCase {
}
+ @Index(name = "ano_1", columnNames = "direct")
+ @Index(name = "ano_2", columnNames = "direct")
+ @MappedSuperclass
+ public static class MappedBaseEntity {
+
+ }
+
+ @Index(name = "ano_3", columnNames = "direct")
@Entity
- public static class TestAnnotationBaseEntity {
+ public static class TestAnnotationBaseEntity extends MappedBaseEntity {
@Where(clause = "SELECT 'mysql' from 1", platforms = Platform.MYSQL)
@Where(clause = "SELECT 'h2' from 1", platforms = Platform.H2)
@@ -45,7 +65,6 @@ public class TestAnnotationBase extends BaseTestCase {
@MetaTest
private String meta;
-
@MetaTest
@Where(clause = "SELECT 'oracle' from 1", platforms = Platform.ORACLE)
private String mixed;
@@ -131,6 +150,13 @@ public class TestAnnotationBase extends BaseTestCase {
assertEquals(40, bp.getDbLength());
}
+ @Test
+ public void annotationClassIndexes() throws SecurityException {
+ BeanDescriptor descriptor = spiEbeanServer().getBeanDescriptor(TestAnnotationBaseEntity.class);
+ final IndexDefinition[] indexDefinitions = descriptor.getIndexDefinitions();
+ assertEquals(3, indexDefinitions.length);
+ }
+
@Test
public void testNotNullWithGroup() throws SecurityException {
BeanDescriptor descriptor = spiEbeanServer().getBeanDescriptor(TestAnnotationBaseEntity.class);
@@ -147,45 +173,41 @@ public class TestAnnotationBase extends BaseTestCase {
@Test
public void testFindAnnotation() throws NoSuchFieldException, SecurityException {
- Field fld = TestAnnotationBaseEntity.class.getDeclaredField("direct");
- String s;
- s = AnnotationUtil.findAnnotation(fld, Where.class, Platform.MYSQL).clause();
- assertEquals("SELECT 'mysql' from 1", s);
+ Field directFld = TestAnnotationBaseEntity.class.getDeclaredField("direct");
+ final DeployBeanProperty direct = createProperty(directFld);
- s = AnnotationUtil.findAnnotation(fld, Where.class, Platform.H2).clause();
- assertEquals("SELECT 'h2' from 1", s);
-
- s = AnnotationUtil.findAnnotation(fld, Where.class, Platform.POSTGRES).clause();
- assertEquals("SELECT 'other' from 1", s);
+ assertEquals("SELECT 'mysql' from 1", where(direct, Platform.MYSQL));
+ assertEquals("SELECT 'h2' from 1", where(direct, Platform.H2));
+ assertEquals("SELECT 'other' from 1", where(direct, Platform.POSTGRES));
// meta
- fld = TestAnnotationBaseEntity.class.getDeclaredField("meta");
-
- s = AnnotationUtil.findAnnotation(fld, Where.class, Platform.MYSQL).clause();
- assertEquals("SELECT 'mysql' from 1", s);
-
- s = AnnotationUtil.findAnnotation(fld, Where.class, Platform.H2).clause();
- assertEquals("SELECT 'h2' from 1", s);
-
- s = AnnotationUtil.findAnnotation(fld, Where.class, Platform.POSTGRES).clause();
- assertEquals("SELECT 'other' from 1", s);
+ Field metaFld = TestAnnotationBaseEntity.class.getDeclaredField("meta");
+ final DeployBeanProperty meta = createProperty(metaFld);
+ assertEquals("SELECT 'mysql' from 1", where(meta, Platform.MYSQL));
+ assertEquals("SELECT 'h2' from 1", where(meta, Platform.H2));
+ assertEquals("SELECT 'other' from 1", where(meta, Platform.POSTGRES));
// mixed
- fld = TestAnnotationBaseEntity.class.getDeclaredField("mixed");
+ Field mixedFld = TestAnnotationBaseEntity.class.getDeclaredField("mixed");
+ final DeployBeanProperty mixed = createProperty(mixedFld);
- s = AnnotationUtil.findAnnotation(fld, Where.class, Platform.MYSQL).clause();
- assertEquals("SELECT 'mysql' from 1", s);
+ assertEquals("SELECT 'mysql' from 1", where(mixed, Platform.MYSQL));
+ assertEquals("SELECT 'h2' from 1", where(mixed, Platform.H2));
+ assertEquals("SELECT 'other' from 1", where(mixed, Platform.POSTGRES));
+ assertEquals("SELECT 'oracle' from 1", where(mixed, Platform.ORACLE));
+ }
- s = AnnotationUtil.findAnnotation(fld, Where.class, Platform.H2).clause();
- assertEquals("SELECT 'h2' from 1", s);
+ private String where(DeployBeanProperty property, Platform platform) {
+ return property.getMetaAnnotationWhere(platform).clause();
+ }
- s = AnnotationUtil.findAnnotation(fld, Where.class, Platform.POSTGRES).clause();
- assertEquals("SELECT 'other' from 1", s);
-
- s = AnnotationUtil.findAnnotation(fld, Where.class, Platform.ORACLE).clause();
- assertEquals("SELECT 'oracle' from 1", s);
+ private DeployBeanProperty createProperty(Field fld) {
+ DeployBeanProperty directProperty = new DeployBeanProperty(null, null, null);
+ directProperty.setField(fld);
+ directProperty.initMetaAnnotations(metaAnnotationsFilter);
+ return directProperty;
}
}
diff --git a/src/test/java/org/tests/basic/TestWhereAnnotation.java b/src/test/java/org/tests/basic/TestWhereAnnotation.java
index 5d02dfcab..9bc32faf9 100644
--- a/src/test/java/org/tests/basic/TestWhereAnnotation.java
+++ b/src/test/java/org/tests/basic/TestWhereAnnotation.java
@@ -12,6 +12,8 @@ import org.junit.Test;
import java.util.List;
+import static org.assertj.core.api.Assertions.assertThat;
+
public class TestWhereAnnotation extends TransactionalTestCase {
@Test
@@ -29,6 +31,6 @@ public class TestWhereAnnotation extends TransactionalTestCase {
q1.findOne();
String s1 = q1.getGeneratedSql();
- Assert.assertTrue(s1.contains("t1.order_date is not null"));
+ assertThat(s1).contains("t1.order_date is not null");
}
}
diff --git a/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java b/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java
index e0e632db8..358c1c8e0 100644
--- a/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java
+++ b/src/test/java/org/tests/compositekeys/TestOnCascadeDeleteChildrenWithCompositeKeys.java
@@ -95,8 +95,10 @@ public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase {
@Entity
@Table(name = "em_user")
public static class User {
+ @Id
private Long id;
private String name;
+ @OneToMany(cascade = CascadeType.REMOVE)
private Set userRoles;
public User() {
@@ -107,7 +109,6 @@ public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase {
this.name = name;
}
- @Id
public Long getId() {
return id;
}
@@ -124,7 +125,6 @@ public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase {
this.name = name;
}
- @OneToMany(cascade = CascadeType.REMOVE)
public Set getUserRoles() {
return userRoles;
}
@@ -138,11 +138,18 @@ public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase {
@Table(name = "em_user_role")
public static class UserRole implements Serializable {
private static final long serialVersionUID = 1L;
- private UserRolePK pk;
- private User user;
- private Role role;
@EmbeddedId
+ private UserRolePK pk;
+
+ @ManyToOne
+ @JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
+ private User user;
+
+ @ManyToOne
+ @JoinColumn(name = "role_id", nullable = false, insertable = false, updatable = false)
+ private Role role;
+
public UserRolePK getPk() {
return pk;
}
@@ -151,8 +158,6 @@ public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase {
this.pk = pk;
}
- @ManyToOne
- @JoinColumn(name = "user_id", nullable = false, insertable = false, updatable = false)
public User getUser() {
return user;
}
@@ -161,8 +166,6 @@ public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase {
this.user = user;
}
- @ManyToOne
- @JoinColumn(name = "role_id", nullable = false, insertable = false, updatable = false)
public Role getRole() {
return role;
}
@@ -213,11 +216,12 @@ public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase {
@Entity
@Table(name = "em_role")
public static class Role {
+ @Id
private Long id;
private String name;
+ @OneToMany(cascade = CascadeType.REMOVE)
private Set userRoles;
- @Id
public Long getId() {
return id;
}
@@ -234,7 +238,6 @@ public class TestOnCascadeDeleteChildrenWithCompositeKeys extends BaseTestCase {
this.name = name;
}
- @OneToMany(cascade = CascadeType.REMOVE)
public Set getUserRoles() {
return userRoles;
}
diff --git a/src/test/java/org/tests/idkeys/db/GenKeySequence.java b/src/test/java/org/tests/idkeys/db/GenKeySequence.java
index eb55ca796..c1bcbb01e 100644
--- a/src/test/java/org/tests/idkeys/db/GenKeySequence.java
+++ b/src/test/java/org/tests/idkeys/db/GenKeySequence.java
@@ -4,10 +4,8 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
-import javax.persistence.SequenceGenerator;
@Entity
-@SequenceGenerator(name = "SEQ_NAME", sequenceName = GenKeySequence.SEQUENCE_NAME)
public class GenKeySequence {
public final static String SEQUENCE_NAME = "SEQ";
diff --git a/src/test/java/org/tests/idkeys/db/GenKeyTable.java b/src/test/java/org/tests/idkeys/db/GenKeyTable.java
deleted file mode 100644
index 0d490881f..000000000
--- a/src/test/java/org/tests/idkeys/db/GenKeyTable.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.tests.idkeys.db;
-
-import javax.persistence.Entity;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
-import javax.persistence.Id;
-
-@Entity
-public class GenKeyTable {
- @Id
- @GeneratedValue(strategy = GenerationType.TABLE)
- private Long id;
-
- private String description;
-
- public Long getId() {
- return id;
- }
-
- public void setId(Long id) {
- this.id = id;
- }
-
- public String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-}
diff --git a/src/test/java/org/tests/model/aggregation/DMachineUse.java b/src/test/java/org/tests/model/aggregation/DMachineUse.java
index 0ab4915e5..d8015931f 100644
--- a/src/test/java/org/tests/model/aggregation/DMachineUse.java
+++ b/src/test/java/org/tests/model/aggregation/DMachineUse.java
@@ -28,6 +28,7 @@ public class DMachineUse extends Model {
private long timeSecs;
+ @Decimal93
private BigDecimal fuel;
@Version
diff --git a/src/test/java/org/tests/model/aggregation/Decimal93.java b/src/test/java/org/tests/model/aggregation/Decimal93.java
new file mode 100644
index 000000000..0e18650f6
--- /dev/null
+++ b/src/test/java/org/tests/model/aggregation/Decimal93.java
@@ -0,0 +1,16 @@
+package org.tests.model.aggregation;
+
+import javax.persistence.Column;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Example meta annotation for @Column
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+@Column(precision = 9, scale = 3)
+public @interface Decimal93 {
+}
diff --git a/src/test/java/org/tests/model/basic/Person.java b/src/test/java/org/tests/model/basic/Person.java
index 2c2cd00ee..39496a703 100644
--- a/src/test/java/org/tests/model/basic/Person.java
+++ b/src/test/java/org/tests/model/basic/Person.java
@@ -18,18 +18,24 @@ public class Person implements Serializable {
private static final long serialVersionUID = 495045977245770183L;
+ @Id
+ @GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
+ @SequenceGenerator(name = "PERSONS_SEQ", initialValue = 1000, allocationSize = 40)
+ @Column(name = "ID", unique = true, nullable = false)
private Long id;
+
+ @Column(name = "SURNAME", nullable = false, unique = false, columnDefinition = "varchar(64)")
private String surname;
+
+ @Column(name = "NAME", nullable = false, unique = false, columnDefinition = "varchar(64)")
private String name;
+
+ @OneToMany(targetEntity = Phone.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "person")
private List phones;
public Person() {
}
- @Id
- @GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
- @SequenceGenerator(name = "PERSONS_SEQ", initialValue = 1000, allocationSize = 40)
- @Column(name = "ID", unique = true, nullable = false)
public Long getId() {
return id;
}
@@ -38,7 +44,6 @@ public class Person implements Serializable {
this.id = id;
}
- @Column(name = "SURNAME", nullable = false, unique = false, columnDefinition = "varchar(64)")
public String getSurname() {
return surname;
}
@@ -47,7 +52,6 @@ public class Person implements Serializable {
this.surname = surname;
}
- @Column(name = "NAME", nullable = false, unique = false, columnDefinition = "varchar(64)")
public String getName() {
return name;
}
@@ -56,7 +60,6 @@ public class Person implements Serializable {
this.name = name;
}
- @OneToMany(targetEntity = Phone.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "person")
public List getPhones() {
return phones;
}
diff --git a/src/test/java/org/tests/model/basic/Phone.java b/src/test/java/org/tests/model/basic/Phone.java
index 94b45624d..3ba7b3ebe 100644
--- a/src/test/java/org/tests/model/basic/Phone.java
+++ b/src/test/java/org/tests/model/basic/Phone.java
@@ -18,16 +18,21 @@ public class Phone implements Serializable {
private static final long serialVersionUID = -326610269092956952L;
+ @Id
+ @GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
+ @Column(name = "id", unique = true, nullable = false)
private Long id;
+
+ @Column(name = "phone_number", nullable = false, unique = true, columnDefinition = "varchar(7)")
private String phoneNumber;
+
+ @ManyToOne(targetEntity = Person.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
+ @JoinColumn(name = "person_id", nullable = false)
private Person person;
public Phone() {
}
- @Id
- @GeneratedValue(strategy = javax.persistence.GenerationType.AUTO)
- @Column(name = "id", unique = true, nullable = false)
public Long getId() {
return id;
}
@@ -36,7 +41,6 @@ public class Phone implements Serializable {
this.id = id;
}
- @Column(name = "phone_number", nullable = false, unique = true, columnDefinition = "varchar(7)")
public String getPhoneNumber() {
return phoneNumber;
}
@@ -46,8 +50,6 @@ public class Phone implements Serializable {
}
@NotNull
- @ManyToOne(targetEntity = Person.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
- @JoinColumn(name = "person_id", nullable = false)
public Person getPerson() {
return person;
}
diff --git a/src/test/java/org/tests/model/embedded/RevisionId.java b/src/test/java/org/tests/model/embedded/RevisionId.java
index b3e32e6bc..dd624cabb 100644
--- a/src/test/java/org/tests/model/embedded/RevisionId.java
+++ b/src/test/java/org/tests/model/embedded/RevisionId.java
@@ -1,6 +1,5 @@
package org.tests.model.embedded;
-import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
@@ -18,7 +17,6 @@ public class RevisionId {
this.primaryId = primaryId;
}
- @Column(name = "revision")
public Integer getRevision() {
return revision;
}