mirror of
https://github.com/ebean-orm/ebean.git
synced 2024-04-21 10:51:47 +00:00
jakarta.validation.constraints.Size
This commit is contained in:
+1
-1
@@ -293,6 +293,6 @@ ebean.tenant.schemaProvider
|
||||
ebean.updateAllPropertiesInBatch
|
||||
ebean.updateChangesOnly
|
||||
ebean.updatesDeleteMissingChildren
|
||||
ebean.useJavaxValidationNotNull
|
||||
ebean.useValidationNotNull
|
||||
ebean.useJtaTransactionManager
|
||||
|
||||
|
||||
@@ -109,6 +109,12 @@
|
||||
<version>1.1.0.Final</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.validation</groupId>
|
||||
<artifactId>jakarta.validation-api</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
|
||||
@@ -40,6 +40,13 @@ public class ClassLoadConfig {
|
||||
return isPresent("javax.validation.constraints.NotNull");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if jakarta validation annotations like Size and NotNull are present.
|
||||
*/
|
||||
public boolean isJakartaValidationAnnotationsPresent() {
|
||||
return isPresent("jakarta.validation.constraints.NotNull");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if javax PostConstruct annotation is present (maybe not in java9).
|
||||
* If not we don't support PostConstruct lifecycle events.
|
||||
|
||||
@@ -489,7 +489,7 @@ public class DatabaseConfig {
|
||||
* Should the javax.validation.constraints.NotNull enforce a notNull column in DB.
|
||||
* If set to false, use io.ebean.annotation.NotNull or Column(nullable=true).
|
||||
*/
|
||||
private boolean useJavaxValidationNotNull = true;
|
||||
private boolean useValidationNotNull = true;
|
||||
|
||||
/**
|
||||
* Generally we want to perform L2 cache notification in the background and not impact
|
||||
@@ -2809,7 +2809,7 @@ public class DatabaseConfig {
|
||||
enabledL2Regions = p.get("enabledL2Regions", enabledL2Regions);
|
||||
notifyL2CacheInForeground = p.getBoolean("notifyL2CacheInForeground", notifyL2CacheInForeground);
|
||||
useJtaTransactionManager = p.getBoolean("useJtaTransactionManager", useJtaTransactionManager);
|
||||
useJavaxValidationNotNull = p.getBoolean("useJavaxValidationNotNull", useJavaxValidationNotNull);
|
||||
useValidationNotNull = p.getBoolean("useValidationNotNull", useValidationNotNull);
|
||||
autoReadOnlyDataSource = p.getBoolean("autoReadOnlyDataSource", autoReadOnlyDataSource);
|
||||
idGeneratorAutomatic = p.getBoolean("idGeneratorAutomatic", idGeneratorAutomatic);
|
||||
|
||||
@@ -3056,20 +3056,21 @@ public class DatabaseConfig {
|
||||
/**
|
||||
* Returns if we use javax.validation.constraints.NotNull
|
||||
*/
|
||||
public boolean isUseJavaxValidationNotNull() {
|
||||
return useJavaxValidationNotNull;
|
||||
public boolean isUseValidationNotNull() {
|
||||
return useValidationNotNull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls if Ebean should ignore <code>&x64;javax.validation.contstraints.NotNull</code>
|
||||
* Controls if Ebean should ignore <code>&x64;javax.validation.contstraints.NotNull</code> or
|
||||
* <code>&x64;jakarta.validation.contstraints.NotNull</code>
|
||||
* with respect to generating a <code>NOT NULL</code> column.
|
||||
* <p>
|
||||
* Normally when Ebean sees javax NotNull annotation it means that column is defined as NOT NULL.
|
||||
* Set this to <code>false</code> and the javax NotNull annotation is effectively ignored (and
|
||||
* we instead use Ebean's own NotNull annotation or JPA Column(nullable=false) annotation.
|
||||
*/
|
||||
public void setUseJavaxValidationNotNull(boolean useJavaxValidationNotNull) {
|
||||
this.useJavaxValidationNotNull = useJavaxValidationNotNull;
|
||||
public void setUseValidationNotNull(boolean useValidationNotNull) {
|
||||
this.useValidationNotNull = useValidationNotNull;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -138,6 +138,12 @@
|
||||
<version>1.1.0.Final</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.validation</groupId>
|
||||
<artifactId>jakarta.validation-api</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
|
||||
+10
-1
@@ -1140,7 +1140,7 @@ public class DeployBeanProperty {
|
||||
return result;
|
||||
}
|
||||
|
||||
public List<Size> getMetaAnnotationSize() {
|
||||
public List<Size> getMetaAnnotationJavaxSize() {
|
||||
final List<Size> size = getMetaAnnotations(Size.class);
|
||||
final List<Size.List> lists = getMetaAnnotations(Size.List.class);
|
||||
for (Size.List list : lists) {
|
||||
@@ -1149,6 +1149,15 @@ public class DeployBeanProperty {
|
||||
return size;
|
||||
}
|
||||
|
||||
public List<jakarta.validation.constraints.Size> getMetaAnnotationJakartaSize() {
|
||||
final List<jakarta.validation.constraints.Size> size = getMetaAnnotations(jakarta.validation.constraints.Size.class);
|
||||
final List<jakarta.validation.constraints.Size.List> lists = getMetaAnnotations(jakarta.validation.constraints.Size.List.class);
|
||||
for (jakarta.validation.constraints.Size.List list : lists) {
|
||||
Collections.addAll(size, list.value());
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public Formula getMetaAnnotationFormula(Platform platform) {
|
||||
Formula fallback = null;
|
||||
for (Annotation ann : metaAnnotations) {
|
||||
|
||||
+9
-3
@@ -4,13 +4,11 @@ import io.ebean.annotation.DbForeignKey;
|
||||
import io.ebean.annotation.FetchPreference;
|
||||
import io.ebean.annotation.TenantId;
|
||||
import io.ebean.annotation.Where;
|
||||
import io.ebean.config.BeanNotRegisteredException;
|
||||
import io.ebean.config.NamingConvention;
|
||||
import io.ebeaninternal.server.deploy.BeanDescriptorManager;
|
||||
import io.ebeaninternal.server.deploy.BeanTable;
|
||||
import io.ebeaninternal.server.deploy.PropertyForeignKey;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanProperty;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssoc;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployBeanPropertyAssocOne;
|
||||
import io.ebeaninternal.server.deploy.meta.DeployTableJoinColumn;
|
||||
import io.ebeaninternal.server.query.SqlJoinType;
|
||||
@@ -117,7 +115,7 @@ public class AnnotationAssocOnes extends AnnotationAssoc {
|
||||
if (nonNull != null) {
|
||||
prop.setNullable(false);
|
||||
}
|
||||
if (validationAnnotations) {
|
||||
if (javaxValidationAnnotations) {
|
||||
NotNull notNull = get(prop, NotNull.class);
|
||||
if (notNull != null && isEbeanValidationGroups(notNull.groups())) {
|
||||
prop.setNullable(false);
|
||||
@@ -125,6 +123,14 @@ public class AnnotationAssocOnes extends AnnotationAssoc {
|
||||
prop.getTableJoin().setType(SqlJoinType.INNER);
|
||||
}
|
||||
}
|
||||
if (jakartaValidationAnnotations) {
|
||||
jakarta.validation.constraints.NotNull notNull = get(prop, jakarta.validation.constraints.NotNull.class);
|
||||
if (notNull != null && isEbeanValidationGroups(notNull.groups())) {
|
||||
prop.setNullable(false);
|
||||
// overrides optional attribute of ManyToOne etc
|
||||
prop.getTableJoin().setType(SqlJoinType.INNER);
|
||||
}
|
||||
}
|
||||
|
||||
// check for manually defined joins
|
||||
BeanTable beanTable = prop.getBeanTable();
|
||||
|
||||
+28
-9
@@ -258,19 +258,38 @@ public class AnnotationFields extends AnnotationParser {
|
||||
}
|
||||
|
||||
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 (javaxValidationAnnotations) {
|
||||
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 (jakartaValidationAnnotations) {
|
||||
jakarta.validation.constraints.NotNull notNull = get(prop, jakarta.validation.constraints.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 (javaxValidationAnnotations) {
|
||||
for (Size size : prop.getMetaAnnotationJavaxSize()) {
|
||||
if (size.max() < Integer.MAX_VALUE) {
|
||||
maxSize = Math.max(maxSize, size.max());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (jakartaValidationAnnotations) {
|
||||
for (jakarta.validation.constraints.Size size : prop.getMetaAnnotationJakartaSize()) {
|
||||
if (size.max() < Integer.MAX_VALUE) {
|
||||
maxSize = Math.max(maxSize, size.max());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (maxSize != -1) {
|
||||
@@ -280,7 +299,7 @@ public class AnnotationFields extends AnnotationParser {
|
||||
}
|
||||
|
||||
private void initTenantId(DeployBeanProperty prop) {
|
||||
if (validationAnnotations) {
|
||||
if (javaxValidationAnnotations || jakartaValidationAnnotations) {
|
||||
initValidation(prop);
|
||||
}
|
||||
if (has(prop, TenantId.class)) {
|
||||
|
||||
@@ -26,14 +26,17 @@ public abstract class AnnotationParser extends AnnotationBase {
|
||||
|
||||
final Class<?> beanType;
|
||||
|
||||
final boolean validationAnnotations;
|
||||
final boolean javaxValidationAnnotations;
|
||||
|
||||
final boolean jakartaValidationAnnotations;
|
||||
|
||||
final ReadAnnotationConfig readConfig;
|
||||
|
||||
AnnotationParser(DeployBeanInfo<?> info, ReadAnnotationConfig readConfig) {
|
||||
super(info.getUtil());
|
||||
this.readConfig = readConfig;
|
||||
this.validationAnnotations = readConfig.isJavaxValidationAnnotations();
|
||||
this.javaxValidationAnnotations = readConfig.isJavaxValidationAnnotations();
|
||||
this.jakartaValidationAnnotations = readConfig.isJakartaValidationAnnotations();
|
||||
this.info = info;
|
||||
this.beanType = info.getDescriptor().getBeanType();
|
||||
this.descriptor = info.getDescriptor();
|
||||
@@ -132,7 +135,7 @@ public abstract class AnnotationParser extends AnnotationBase {
|
||||
* can be applied to DDL generation.
|
||||
*/
|
||||
boolean isEbeanValidationGroups(Class<?>[] groups) {
|
||||
if (!util.isUseJavaxValidationNotNull()) {
|
||||
if (!util.isUseValidationNotNull()) {
|
||||
return false;
|
||||
}
|
||||
return groups.length == 0 || groups.length == 1 && Default.class.isAssignableFrom(groups[0]);
|
||||
|
||||
@@ -57,7 +57,7 @@ public class DeployUtil {
|
||||
|
||||
private final Encryptor bytesEncryptor;
|
||||
|
||||
private final boolean useJavaxValidationNotNull;
|
||||
private final boolean useValidationNotNull;
|
||||
|
||||
public DeployUtil(TypeManager typeMgr, DatabaseConfig config) {
|
||||
this.typeManager = typeMgr;
|
||||
@@ -67,7 +67,7 @@ public class DeployUtil {
|
||||
this.encryptKeyManager = config.getEncryptKeyManager();
|
||||
Encryptor be = config.getEncryptor();
|
||||
this.bytesEncryptor = be != null ? be : new SimpleAesEncryptor();
|
||||
this.useJavaxValidationNotNull = config.isUseJavaxValidationNotNull();
|
||||
this.useValidationNotNull = config.isUseValidationNotNull();
|
||||
}
|
||||
|
||||
public TypeManager getTypeManager() {
|
||||
@@ -286,8 +286,8 @@ public class DeployUtil {
|
||||
return type.equals(String.class);
|
||||
}
|
||||
|
||||
boolean isUseJavaxValidationNotNull() {
|
||||
return useJavaxValidationNotNull;
|
||||
boolean isUseValidationNotNull() {
|
||||
return useValidationNotNull;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package io.ebeaninternal.server.deploy.parse;
|
||||
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
class InitMetaJakartaValidationAnnotation {
|
||||
|
||||
static void init(ReadAnnotationConfig readConfig) {
|
||||
readConfig.addMetaAnnotation(Size.class);
|
||||
readConfig.addMetaAnnotation(Size.List.class);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -2,7 +2,7 @@ package io.ebeaninternal.server.deploy.parse;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
class InitMetaValidationAnnotation {
|
||||
class InitMetaJavaxValidationAnnotation {
|
||||
|
||||
static void init(ReadAnnotationConfig readConfig) {
|
||||
readConfig.addMetaAnnotation(Size.class);
|
||||
+6
@@ -21,6 +21,7 @@ class ReadAnnotationConfig {
|
||||
private final boolean disableL2Cache;
|
||||
private final boolean eagerFetchLobs;
|
||||
private final boolean javaxValidationAnnotations;
|
||||
private final boolean jakartaValidationAnnotations;
|
||||
private final boolean jacksonAnnotations;
|
||||
private final boolean idGeneratorAutomatic;
|
||||
|
||||
@@ -34,6 +35,7 @@ class ReadAnnotationConfig {
|
||||
this.eagerFetchLobs = config.isEagerFetchLobs();
|
||||
this.idGeneratorAutomatic = config.isIdGeneratorAutomatic();
|
||||
this.javaxValidationAnnotations = generatedPropFactory.getClassLoadConfig().isJavaxValidationAnnotationsPresent();
|
||||
this.jakartaValidationAnnotations = generatedPropFactory.getClassLoadConfig().isJakartaValidationAnnotationsPresent();
|
||||
this.jacksonAnnotations = generatedPropFactory.getClassLoadConfig().isJacksonAnnotationsPresent();
|
||||
this.metaAnnotations.add(Column.class);
|
||||
this.metaAnnotations.add(Formula.class);
|
||||
@@ -75,6 +77,10 @@ class ReadAnnotationConfig {
|
||||
return javaxValidationAnnotations;
|
||||
}
|
||||
|
||||
boolean isJakartaValidationAnnotations() {
|
||||
return jakartaValidationAnnotations;
|
||||
}
|
||||
|
||||
boolean isJacksonAnnotations() {
|
||||
return jacksonAnnotations;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@ public class ReadAnnotations {
|
||||
public ReadAnnotations(GeneratedPropertyFactory generatedPropFactory, String asOfViewSuffix, String versionsBetweenSuffix, DatabaseConfig config) {
|
||||
this.readConfig = new ReadAnnotationConfig(generatedPropFactory, asOfViewSuffix, versionsBetweenSuffix, config);
|
||||
if (readConfig.isJavaxValidationAnnotations()) {
|
||||
InitMetaValidationAnnotation.init(readConfig);
|
||||
InitMetaJavaxValidationAnnotation.init(readConfig);
|
||||
}
|
||||
if (readConfig.isJakartaValidationAnnotations()) {
|
||||
InitMetaJakartaValidationAnnotation.init(readConfig);
|
||||
}
|
||||
if (readConfig.isJacksonAnnotations()) {
|
||||
InitMetaJacksonAnnotation.init(readConfig);
|
||||
|
||||
@@ -144,6 +144,69 @@ public class TestAnnotationBase extends BaseTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Entity
|
||||
public static class TestJakartaAnnotationBaseEntity extends MappedBaseEntity {
|
||||
@Where(clause = "SELECT 'mysql' from 1", platforms = Platform.MYSQL)
|
||||
@Where(clause = "SELECT 'h2' from 1", platforms = H2)
|
||||
@Where(clause = "SELECT 'other' from 1")
|
||||
private String direct;
|
||||
|
||||
@MetaTest
|
||||
private String meta;
|
||||
|
||||
@MetaTest
|
||||
@Where(clause = "SELECT 'oracle' from 1", platforms = Platform.ORACLE)
|
||||
private String mixed;
|
||||
|
||||
@jakarta.validation.constraints.Size.List({
|
||||
@jakarta.validation.constraints.Size(max = 10, message = "max length for you is 10"),
|
||||
@jakarta.validation.constraints.Size(min = 1),
|
||||
@jakarta.validation.constraints.Size(max = 40, message = "max value for you is 40", groups = ValidationGroupSomething.class)
|
||||
})
|
||||
private String constraintAnnotation;
|
||||
|
||||
@NotNull
|
||||
private String null1;
|
||||
|
||||
|
||||
@NotNull(groups = ValidationGroupSomething.class)
|
||||
private String null2;
|
||||
|
||||
private String null3;
|
||||
|
||||
public String getConstraintAnnotation() {
|
||||
return constraintAnnotation;
|
||||
}
|
||||
|
||||
public void setConstraintAnnotation(String constraintAnnotation) {
|
||||
this.constraintAnnotation = constraintAnnotation;
|
||||
}
|
||||
|
||||
public String getNull1() {
|
||||
return null1;
|
||||
}
|
||||
|
||||
public void setNull1(String null1) {
|
||||
this.null1 = null1;
|
||||
}
|
||||
|
||||
public String getNull2() {
|
||||
return null2;
|
||||
}
|
||||
|
||||
public void setNull2(String null2) {
|
||||
this.null2 = null2;
|
||||
}
|
||||
|
||||
public String getNull3() {
|
||||
return null3;
|
||||
}
|
||||
|
||||
public void setNull3(String null3) {
|
||||
this.null3 = null3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testFindMaxSize() throws SecurityException {
|
||||
@@ -152,6 +215,13 @@ public class TestAnnotationBase extends BaseTestCase {
|
||||
assertEquals(40, bp.getDbLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindJakartaMaxSize() throws SecurityException {
|
||||
BeanDescriptor<TestJakartaAnnotationBaseEntity> descriptor = spiEbeanServer().getBeanDescriptor(TestJakartaAnnotationBaseEntity.class);
|
||||
BeanProperty bp = descriptor.findProperty("constraintAnnotation");
|
||||
assertEquals(40, bp.getDbLength());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void annotationClassIndexes() throws SecurityException {
|
||||
BeanDescriptor<TestAnnotationBaseEntity> descriptor = spiEbeanServer().getBeanDescriptor(TestAnnotationBaseEntity.class);
|
||||
@@ -173,6 +243,20 @@ public class TestAnnotationBase extends BaseTestCase {
|
||||
assertTrue(bp.isNullable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJakartaNotNullWithGroup() throws SecurityException {
|
||||
BeanDescriptor<TestJakartaAnnotationBaseEntity> descriptor = spiEbeanServer().getBeanDescriptor(TestJakartaAnnotationBaseEntity.class);
|
||||
|
||||
BeanProperty bp = descriptor.findProperty("null1");
|
||||
assertFalse(bp.isNullable());
|
||||
|
||||
bp = descriptor.findProperty("null2");
|
||||
assertTrue(bp.isNullable());
|
||||
|
||||
bp = descriptor.findProperty("null3");
|
||||
assertTrue(bp.isNullable());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFindAnnotation() throws NoSuchFieldException, SecurityException {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user