I have a configuration file which contains this line:
login.mode=PASSWORD
and an enum
public enum LoginMode {
PASSWORD, NOT_PASSWORD, OTHER }
and a spring bean
<bean id="environment" class="a.b.c.Environment" init-method="init">
<property name="loginMode" value="${login.mode}"/>
</bean>
and of course a bean class
public class Environment {
private LoginMode loginMode;
public LoginMode getLoginMode() {
return loginMode;
}
public void setLoginMode(LoginMode loginMode) {
this.loginMode = loginMode;
}
}
How can i convert the property of the configuration file (which is a String) into the corresponding enum value of LoginMode?
EDIT: i know how to get the enum value of a string input, but the issue is another one:
If i try this:
public class Environment {
private LoginMode loginMode;
public LoginMode getLoginMode() {
return loginMode;
}
public void setLoginMode(String loginMode) {
this.loginMode = LoginMode.valueOf(loginMode);
}
}
spring is complaining about getter and setter not having the same input and output type.
Bean property 'loginMode' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
Spring automatically converts input Strings to the corresponding valueOf of the desired enum.
You can do that by
LoginMode.valueOf("someString");
LoginMode.valueOf(valueOfProperty);
EDIT:
Try using converter
http://docs.spring.io/spring/docs/3.0.0.RC2/reference/html/ch05s05.html
http://forum.spring.io/forum/spring-projects/web/83191-custom-enum-string-converters
EDIT2:
also check this:
How assign bean's property an Enum value in Spring config file?
Related
I have a Spring 4.3 custom PropertyPlaceholderConfigurer that does extra processing on values read from the properties files before injection:
public class MyPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer{
#Override
protected String convertPropertyValue(final String originalValue) { ... }
#Override
protected String resolveSystemProperty(final String key) {
return convertPropertyValue(super.resolveSystemProperty(key));
}
}
My problem is that bean fields that are annotated for injection with property values, eg. #Value("${some_property}"), are in fact injected with the raw value read from the property source without my custom processing.
After some debugging I found that I should have also overiden com.ec.survey.security.SafePasswordPropertyPlaceholderConfigurer#resolvePlaceholder
This may be silly question to ask but i'm unable to find any satisfactory solution to my problem. In java we don't have the concept of default variables so i am trying to give default value from properties file to my function parameters/arguments using #Value annotation, but i'm always getting null and i'm unable to figure why is this happening. Please help me to solve the issue or provide me some appropriate link/reference which may solve my issue.
MainApplication.java
#SpringBootApplication
public class Application
{
public static void main(String[] args)
{
ApplicationContext context = SpringApplication.run(NetappApplication.class, args);
Sample sample = context.getBean(Sample.class);
System.out.println(sample.check(null));
}
}
Sample.java
public interface Sample
{
public String check(String message);
}
SampleImpl.java
#Service
#PropertySource("classpath:app.properties")
public class SampleImpl implements Sample
{
#Value("${test}")
String message1;
#Override
public String check(#Value("${test}") String message)
{
return message;
}
}
app.properties
test=anand
But you are passing null to your method...
Perhaps what you want to do is to assign default value to test in case it's not defined in property file:
#Value("${test:default}");
Then, when properties are autowired by Spring if placeholder resolver doesn't get the value from props file, it will use what is after :.
The best use case for this (that I can think of) is when you create Spring configuration.
Let's say you have a configuration class: for DB access. Simply put:
#Configuration
public class DbConfig {
#Value("${url:localhost}")
String dbUrl;
// rest for driver, user, pass etc
public DataSource createDatasource() {
// here you use some DataSourceBuilder to configure connection
}
}
Now, when Spring application starts up, properties' values are resolved, and as I wrote above you can switch between value from property and a default value. But it is done once, when app starts and Spring creates your beans.
If you want to check incoming argument on runtime, simple null check will be enough.
#Value("${test}")
String message1;
#Override
public String check(String message) {
if (message == null) {
return message1;
}
}
I wrote a an attribute converter. I want to apply that in an entity. I'm following a purely XML approach so far.
I could not find an equivalent of #Convert in hbm notation.
An example would be appreciated.
When I search for this, understandably, Google returns lots of results about tools/methods on "Auto Converting hbm files to entities vice versa".
Edit:
Now I'm suspecting if there is an option in hbm file, given that this is JPA annotation.
The doc of #Convert says:
The Convert annotation is used to specify the conversion of a Basic
field or property. It is not necessary to use the Basic annotation or
corresponding XML element to specify the basic type.
I'm not entirely sure what it means. Is mixing annotation and XML a way to go in this case?
I've tried this:
public class Person {
//this is enum
private Ethnicity ethnicity;
//.....
}
public enum Ethnicity{
INDIAN("IND"),
PERSIAN("PER")
//...constructors and value field.
public String value(){
return this.value;
}
public Ethnicity fromValue(String value){
//logic for conversion
}
}
Converter:
#Converter
public class EthnicityConverter implements AttributeConverter<Ethnicity,String> {
#Override
public Ethnicity convertToEntityAttribute(String attribute) {
if ( attribute == null ) {
return null;
}
return Ethnicity.fromValue( attribute );
}
#Override
public String convertToDatabaseColumn(Ethnicity dbData) {
if ( dbData == null ) {
return null;
}
return dbData.value();
}
}
HBM File:
//....other columns
<property name="ethnicity">
<column name="ethnicity"/>
<type name="EthnicityConverter"/>
</property>
//....other columns
Edit: Corrected the converter code.
The answer from Sarvana is close - you do in fact use the type XML attribute. However, type is used to name a Hibernate Type. However there is a convention to name, instead, an AttributeConverter - simply apply the prefix converted:: to your AttributeConverter FQN. E.g.,
<property name="ethnicity">
<column name="ethnicity"/>
<type name="converted::EthnicityConverter"/>
</property>
The other option is to auto-apply the converter:
#Converter( autoApply=true)
public class EthnicityConverter implements AttributeConverter<Ethnicity,String> {
...
}
Given the converter above, so long as Hibernate knows about it, Hibernate will apply that to any attribute of type Ethnicity.
HTH
type is the equivalent xml attribute for Convert annotation.
Below is to convert to Y/N in DB and Boolean in entity.
<property name="status" column="book_status" type="yes_no" not-null="true"/>
Just replace yes_no with your custom converter class
Please see my answer at
https://stackoverflow.com/a/37914271/3344829
Official documentation
https://docs.jboss.org/hibernate/orm/4.2/manual/en-US/html/ch06.html
Update
<property name="ethnicity" column="ethnicity" type="com.example.EthnicityConverter"/>
Update
#Converter
public class EthnicityConverter implements AttributeConverter<Ethnicity, String> {
#Override
public String convertToDatabaseColumn(Ethnicity attribute) {
// TODO return String value of enum
}
#Override
public Ethnicity convertToEntityAttribute(String dbData) {
// TODO return resolved enum from string
}
}
I too had to face this issue and i was able to resolve it.
Refer : Hibernate 5 Documentation Example 33. HBM mapping for AttributeConverter
We have to use exact class with package.
Ex :
<property name="ethnicity" column="ethnicity" type="converted::com.example.EthnicityConverter"/>
i am trying to decalre a spring bean on a xml (Mule config file), and i've created a bean like that:
<bean id="IsActiveFilter" class="com.TimeLineListener.IsActiveFilter">
<property name="isChatActive" value="${chatListener.isActive}"/>
</bean>
Now, my question is - how can i get tothe value of isChatActive from within the actual bean class? i mean, can i just create a variable (private int isChatActive) with the name isChatActive and it will get whatever value the placeholder gives it? i mean something like:
public class IsActiveFilter{
{
private int isChatActive;
}
Will that work? if not, how do i use it?
thanks in advance
Create a getter and setter and you are fine:
public class IsActiveFilter{
private int isChatActive;
public int getIsChatActive() {
return this.isChatActive;
}
public void setIsChatActive(int isChatActive) {
this.isChatActive = isChatActive;
}
}
public class IsActiveFilter {
private int chatActive;
public boolean isChatActive() {
return chatActive;
}
public void setChatActive(boolean chatActive) {
this.chatActive = chatActive;
}
}
I am using spring in my application , When i am loading the springApplicationContext to get the beans i am getting the errors
Caused by:
org.springframework.beans.InvalidPropertyException:
Invalid property "abc"
Even though there is a property abc and the setter for that property in the bean.
This is a weird error i know , but i can't figure out where is the problem.
Any pointers will be helpful.
Thanks!
Pratik
Ensure that the property has both a public setter and getter. In case of an AnyObject property it should look like:
private AnyObject abc;
public AnyObject getAbc() { return abc; }
public void setAbc(AnyObject abc) { this.abc = abc; }
There is however one special case: in case of a boolean property it should look like:
private boolean abc;
public boolean isAbc() { return abc; }
public void setAbc(boolean abc) { this.abc = abc; }
Note the is prefix instead of get.
I remeber the similar question at Spring forums. It was found out that there was a setter signature like
public class MyClass {
private Aggregated field;
public MyClass setField(Aggregated field) {
this.field = field;
}
}
I.e. the setter's return type was not void.
Anyway, Spring uses standard Instrospector for processing class properties. Try it with your class and check if target property is found.