or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

bean-validation.mdbootstrap-configuration.mdconstraints.mdcontainer-validation.mdcustom-constraints.mdindex.mdmetadata.mdmethod-validation.mdvalidation-groups.md

validation-groups.mddocs/

0

# Validation Groups

1

2

Group-based validation for conditional constraint application and validation sequencing with group conversion support during cascading validation.

3

4

## Capabilities

5

6

### Default Group

7

8

Marker interface representing the default validation group.

9

10

```java { .api }

11

/**

12

* Default validation group

13

* Constraints belong to this group unless explicitly assigned to other groups

14

*/

15

interface Default {}

16

```

17

18

### Group Sequence

19

20

Annotation for defining sequential validation of groups.

21

22

```java { .api }

23

/**

24

* Defines a sequence of groups that should be validated sequentially

25

* If validation fails for one group, subsequent groups are not validated

26

*/

27

@Target({TYPE})

28

@Retention(RUNTIME)

29

@interface GroupSequence {

30

/**

31

* The sequence of groups to validate

32

* @return array of group classes

33

*/

34

Class<?>[] value();

35

}

36

```

37

38

### Group Conversion

39

40

Annotation for converting validation groups during cascading validation.

41

42

```java { .api }

43

/**

44

* Converts validation groups during cascaded validation

45

* Applied to fields, method parameters, and return values marked with @Valid

46

*/

47

@Target({FIELD, METHOD, CONSTRUCTOR, PARAMETER, TYPE_USE})

48

@Retention(RUNTIME)

49

@Repeatable(ConvertGroup.List.class)

50

@interface ConvertGroup {

51

/**

52

* The source group to convert from

53

* @return source group class

54

*/

55

Class<?> from();

56

57

/**

58

* The target group to convert to

59

* @return target group class

60

*/

61

Class<?> to();

62

63

/**

64

* Container for multiple ConvertGroup annotations

65

*/

66

@Target({FIELD, METHOD, CONSTRUCTOR, PARAMETER, TYPE_USE})

67

@Retention(RUNTIME)

68

@interface List {

69

ConvertGroup[] value();

70

}

71

}

72

```

73

74

**Usage Examples:**

75

76

```java

77

import jakarta.validation.*;

78

import jakarta.validation.constraints.*;

79

import jakarta.validation.groups.*;

80

81

// 1. Define validation groups

82

interface BasicInfo {}

83

interface AdvancedInfo {}

84

interface AdminInfo {}

85

86

// 2. Apply constraints to specific groups

87

public class User {

88

@NotNull(groups = {BasicInfo.class, AdvancedInfo.class})

89

@Size(min = 2, max = 50, groups = BasicInfo.class)

90

private String name;

91

92

@NotNull(groups = BasicInfo.class)

93

@Email(groups = BasicInfo.class)

94

private String email;

95

96

@Min(value = 18, groups = AdvancedInfo.class)

97

private Integer age;

98

99

@NotNull(groups = AdminInfo.class)

100

private String adminRole;

101

102

// constructors, getters, setters...

103

}

104

105

// 3. Group sequence for ordered validation

106

@GroupSequence({BasicInfo.class, AdvancedInfo.class, AdminInfo.class})

107

interface UserValidationSequence {}

108

109

// 4. Validate with specific groups

110

public class ValidationGroupExample {

111

private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

112

113

public void validateUserGroups() {

114

User user = new User();

115

user.setName(""); // Invalid for BasicInfo

116

user.setAge(15); // Invalid for AdvancedInfo

117

118

// Validate only basic information

119

Set<ConstraintViolation<User>> basicViolations =

120

validator.validate(user, BasicInfo.class);

121

System.out.println("Basic validation violations: " + basicViolations.size());

122

123

// Validate advanced information

124

Set<ConstraintViolation<User>> advancedViolations =

125

validator.validate(user, AdvancedInfo.class);

126

System.out.println("Advanced validation violations: " + advancedViolations.size());

127

128

// Validate with sequence (stops at first failing group)

129

Set<ConstraintViolation<User>> sequenceViolations =

130

validator.validate(user, UserValidationSequence.class);

131

System.out.println("Sequence validation violations: " + sequenceViolations.size());

132

133

// Validate multiple groups at once

134

Set<ConstraintViolation<User>> multiGroupViolations =

135

validator.validate(user, BasicInfo.class, AdvancedInfo.class);

136

System.out.println("Multi-group validation violations: " + multiGroupViolations.size());

137

}

138

}

139

140

// 5. Group conversion in cascading validation

141

public class Order {

142

@NotNull

143

@Valid

144

@ConvertGroup(from = Default.class, to = BasicInfo.class)

145

private User customer; // When validating Order, customer uses BasicInfo group

146

147

@Valid

148

@ConvertGroup(from = BasicInfo.class, to = AdvancedInfo.class)

149

@ConvertGroup(from = AdvancedInfo.class, to = AdminInfo.class)

150

private User assignedAgent; // Multiple group conversions

151

152

@NotNull(groups = BasicInfo.class)

153

private String orderNumber;

154

155

// constructors, getters, setters...

156

}

157

158

// 6. Dynamic group validation

159

public class UserRegistrationService {

160

private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

161

162

public ValidationResult validateUser(User user, String validationLevel) {

163

Class<?>[] groups;

164

165

switch (validationLevel) {

166

case "basic":

167

groups = new Class<?>[]{BasicInfo.class};

168

break;

169

case "advanced":

170

groups = new Class<?>[]{BasicInfo.class, AdvancedInfo.class};

171

break;

172

case "admin":

173

groups = new Class<?>[]{UserValidationSequence.class};

174

break;

175

default:

176

groups = new Class<?>[]{Default.class};

177

}

178

179

Set<ConstraintViolation<User>> violations = validator.validate(user, groups);

180

return new ValidationResult(violations.isEmpty(), violations);

181

}

182

}

183

184

// 7. Conditional validation based on object state

185

public class ConditionalUser {

186

@NotNull

187

private String username;

188

189

@NotNull(groups = PremiumUser.class)

190

@Size(min = 10, groups = PremiumUser.class)

191

private String premiumFeature;

192

193

private boolean isPremium;

194

195

public Set<ConstraintViolation<ConditionalUser>> validate() {

196

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

197

198

if (isPremium) {

199

return validator.validate(this, Default.class, PremiumUser.class);

200

} else {

201

return validator.validate(this, Default.class);

202

}

203

}

204

205

interface PremiumUser {}

206

}

207

```