I have the following Test.java POJO class being populated from a property file using the #ConfigurationProperties annotation. I have seen the usage of #Required annotation to make it a mandatory.
Rather than defining annotations at the setter method level, are there any annotations or options within the #Value annotation that I can use for defining conditions like Mandatory, NotNull, etc?
#Component
#ConfigurationProperties(prefix = "com.test")
public class Test {
private String name;
#Required
public void setName(String name) {
name = name;
}
public String getName(String name) {
name = name;
}
}
Is this the right and only way for making a particular attribute mandatory? What are the other such annotations I could use for such conditions or validations purpose?
You can use validation for the properties, just not in the way you envisaged.
What you can do is use standard validation annotations (like #NotNull etc.) on the fields (or setters) themselves.
For example
#NotNull
#Size(min=2, max=10)
private String name;
Check out this part of the documentation
What the documentation essentially says, is that you simply have to have a compatible JSR303 validator implementation on the classpath, and use the relevant annotations.
Spring Boot will take care of the rest
According to the Spring docs (currently 4.1.6.RELEASE), the Value annotation only has a single property, value, containing the value of the property. You can put a Spring EL expression in this, but that won't let you explicitly express notions like non-nullity.
Further, in your code snippet you're using #ConfigurationProperties which is an alternative approach to configuring property values, compared to the #Value annotation.
The way you're doing it, your Java getter/setter names need to map to the property names, i.e. prefix "com.test" + getName() / setName() matches property com.test.name=...
So, you don't need the #Value annotation to tell Spring what property to use.
With the #Value approach, your getters/setters don't have to match the property names, but you do have to annotate each property e.g. #Value("${com.test.name}") and on the class, a #PropertySource annotation pointing to the properties file that contains com.test.name=...
I found a couple of blog posts with code examples that use the 2 different ways to inject the same properties: http://blog.codeleak.pl/2014/09/using-configurationproperties-in-spring.html and http://blog.codeleak.pl/2014/09/testing-mail-code-in-spring-boot.html
Related
I have a dto used as request body in a rest service:
#Data
public class MyClass {
#JsonAlias("myAlias")
private String myProperty;
}
When we produce our openapi/swagger yaml the property name is "myProperty"
Is it possible to automatically force the alias inside the openapi/swagger produced?
(annotation? during yaml creation? anything else?)
Serialization always uses the primary name - in this case, myProperty. In order to change the outputted name, you'd need to change the name of myProperty. The JsonAlias annotation only affects deserialization - the alias is an alternate name.
I am using Bean Validation constraints to validate class instances at run time. I have many DTOs where each has multiple fields often with a common constraint. I want to add a constraint to the class so that it applies to all the properties of the class. (As lombok #NotNull constraint).
e.g
class Person {
#NotNull
private String name;
#NotNull
private String address;
#NotNULL
private String contact;
}
I want to make it something like this.
#NotNull
class Person {
private String name;
private String address;
private String contact
}
You cannot do this with plain Bean Validation. So just adding #NotNull to the class won't work.
One potential approach could be to utilize XML configuration. The idea would be to have your own annotation MyNotNull. Your framework would need to scan for these annotations and build the programmatic configuration for the class in question. This could for example be done via a annotation processor during compile time. Once you have the constraint mapping XML files add them to your jar and reference them in validation.xml. That's just a basic idea. Personally, I am not sure whether it is worth the effort.
So, I was banging my head against the monitor for the last 4 hours and can't figure it out.
I am using Dozer for mapping and it works fine. However, I need one of my DAOs in the destination class and autowiring returns null. Here is a snippet of the class:
#Component
public class Address
{
#XmlElement(name = "street", required = true)
protected String street;
#XmlElement(name = "city", required = true)
protected String city;
#XmlElement(name = "zip", required = true)
protected zip;
#Autowired
private CityDao cityDao;
// Getters/setters
}
the cityDao is always null. I am fairly new to both Spring and Dozer, but the Dozer docs say that the destination classes are created with default constructors and as far as I understand the Spring should not have any problems with it. The cityDao is null though. Please help!
As has been mentioned in the comments, you should not be injecting a DAO into a DTO!
However if you absolutely need to do that for some reason, check out Spring's #Configurable support. Here is the Javadoc and also some more information here and here.
If setup correctly, it allows objects that are not explicitly managed by Spring, to benefit from features like auto-wiring dependencies.
In you example code, Address although being annotated with #Component, is not managed by Spring since it's being created using Dozer. That's why you would need #Configurable to inject CityDao into Address
It seems that the naming conventions between Xtend and Spring Data are incompatible.
For example:
// User.xtend
class User {
#Property
var Long id;
}
interface UserRepository extends JpaRepository<User> {
public User findById(Long id)
}
The #Property annotation renames id to _id, which causes Spring Data to fail, claiming No property id found
Is there a way to either:
Suppress Xtend's renaming of the field
"Teach" Spring Data about the naming convention (Looking for a field? Add an underscore)
Instruct Spring Data to use property-access, rather than field-access for the property resolution?
Any of these would solve this issue, I believe.
Since 2.7.3 the #Property annotation has been superceded by #Accessors, which no longer prepends the fields with an underscore.
Before 2.7.3 you have to build your own #Property annotation which doesn't prepend an underscore to the field's name.
See http://www.eclipse.org/xtend/documentation.html#activeAnnotations
(updated)
I have a bean like:
#Data
public static class ClassUnderTest {
#NotNull
private String field1;
#NotNull
#Since(2.0)
private String field2;
#NotNull
#Until(3.0)
private String field3;
}
#Since and #Until are Gson annotations that permits to avoid serializing / deserializing some fields on my REST API, for certain API versions.
I perform bean validation on the input payload of this API to raise constraint violations.
I'd like to be able to not raise the same violations per version, based on the Gson annotations (and not groups!).
Is there a way, from a ConstraintViolation<T>, to get the Member (like Method / Field) which produced the violation, so that I check if it is annotated by something?
Is there a way to handle validation versionning with Bean Validation?
The only solution I have seems to retrieve that member from the path (getPropertyPath), but it seems not easy to do...
You could retrieve the property name from the violation via getPropertyPath(). That said, assigning your constraints to groups corresponding to the versions might be the better approach. Note that validation groups can also extend existing groups, this might be helpful to model constraints added in a newer version.