Reg Spring #Entity annotation - java

I have a class which has the annotation
#Entity(value = "mongo_collection_name", noClassnameStored = true)
public class Class_Name{ .... }
As you see in the above code snippet, the mongo collection name is hard coded. Can I get this value from a properties file or Consul? What should I do in order to read it from properties file or Consul?

You can create a conf file and load them as dynamic properties using annotations Configuration and PropertySource
Follow the steps:
Create a conf file with the property. For example: /path/to/file.conf
collectionName=mongo_collection_name
Create a Configuration class
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.PropertySource
#Configuration
#PropertySource("file:/path/to/file.conf")
class AppProperties {
}
Now you can get the value with annotation Value in either Service class or Application like below
#Value("${collectionName}")
String collectionName
Let me know if you have questions.

Related

Rewrite a property name in Spring Boot

I have a library that has a configuration class with #ConfigurationProperties(prefix ="b") and #ConditionalOnProperty(prefix = "b", name= "c"), in the project where I included this configuration class, the property "b" is nested under a property called "a" instead of being at the root level of the properties.yml, with this the property "b" name is "a.b" and the configuration class will get ignored, the property name needs to be kept "a.b" in the property file, is there a way to tell spring boot to ignore the "a" prefix for the property "b" or to rewrite the property name from "a.b" to "b" after application.yml gets loaded ?
You can (probably, depending on the exact context of the config class you're working with) use YAML anchor and alias to meet this need. YAML anchors are similar to anchors (<a> tags) in HTML; you mark some part of the yaml with an anchor, then refer to it with a reference somewhere else. The reference is an alias to the anchored value.
In your example, assuming the conditional config class is something like this:
#Configuration
#ConditionalOnProperty(prefix = "b", name = "foo")
#ConfigurationProperties(prefix ="b")
#Getter #Setter
public class SO_75435896 {
private String foo;
}
You can have a YAML config like this to populate it:
a.b: &b-alias
foo: bar
b: *b-alias
The anchor name (b-alias in my example) can be whatever you want, there's nothing special about that name I chose.
If you want to read more about YAML anchors, this is a decent explanation. It's part of Bitbucket documentation, but provides a pretty good general-purpose explanation with examples. There are, of course, plenty of other web pages about YAML anchors.
So your configuration class and properties files cannot be adapted. You can rename it at runtime in your application.yml :
BProperties
#ConfigurationProperties(prefix ="b")
public class BProperties {
private String c;
private String d;
}
And this properties file :
my-props-file.properties
a.b.c=value1
a.b.d=value2
You can rename the properties at runtime in your application.yml (define in classpath under src/main/ressources/) :
application.yml
b:
c: ${a.b.c}
d: ${a.b.d}

Inject values with Spring and YAML with nested properties

I want to inject some values from a YAML to the Spring context.
The structure of the YAML is similar so I did not want to duplicate code, but the Spring startup is failing because it is not being able to inject the value to the placeholder.
Please note my application.properties:
server.port=8084
activeProfile=dev
autoAgents.supplier.id=0
autoAgents.supplier.name=test
autoAgents.supplier.serviceType=REST
autoAgents.supplier.authType=1
autoAgents.supplier.adapter=test
autoAgents.supplier.username=test
autoAgents.supplier.secret=test
autoAgents.supplier.apiPassword=12345
autoAgents.client.id=1
autoAgents.client.name=test
autoAgents.client.serviceType=REST
autoAgents.client.authType=1
autoAgents.client.adapter=
autoAgents.client.username=test
autoAgents.client.secret=test
autoAgents.client.apiPassword=12345
Then I am injecting this values on the YAML, application.yml
activeProfile: ${activeProfile}
autoAgents:
supplier:
isSupplier: true
meta:
id: ${autoAgents.supplier.id}
name: ${autoAgents.supplier.name}
serviceType: ${autoAgents.supplier.serviceType}
authType: ${autoAgents.supplier.authType}
adapter: ${autoAgents.supplier.adapter}
credentials:
username: ${autoAgents.supplier.username}
secret: ${autoAgents.supplier.secret}
apiPassword: ${autoAgents.supplier.apiPassword}
client:
isSupplier: false
meta:
id: ${autoAgents.client.id}
name: ${autoAgents.client.name}
serviceType: ${autoAgents.client.serviceType}
authType: ${autoAgents.client.authType}
adapter: ${autoAgents.client.adapter}
credentials:
username: ${autoAgents.client.username}
secret: ${autoAgents.client.secret}
apiPassword: ${autoAgents.client.apiPassword}
And then I am importing this to a configuration property context:
#Configuration
#EnableConfigurationProperties
#ConfigurationProperties
#Data
public class TwoConnectConfigurationProperties {
private String activeProfile;
#Value("${autoAgents.supplier}")
private AutoAgentDup supplier;
#Value("${autoAgents.client}")
private AutoAgentDup client;
}
But #Value("${autoAgents.supplier}") is not working.
Please advise.
As mentioned earlier it does not make sense to inject values to yaml, you can just create the "application.yaml" with the values directly. And just delete the ".properies" file.
You might want to take a look how to easily inject the properties with common suffix into a bean. Its nicely described here:
https://www.baeldung.com/configuration-properties-in-spring-boot
You will have a bean:
#Configuration
#ConfigurationProperties(prefix = "autoAgents.supplier")
public class AutoAgentSupplierProperties {
private long id;
private String name;
// ... rest of the properies properties
}
You might want the same for the "auto.agent" client.
If you want to avoid code duplication, you can have a bean with the common properties. Extend that class with 2 new classes. One for supplier and one for agent - and annotate those with
#ConfigurationProperties
annotation.
Why you need "nested properties"? If you only want to access them in application, just take values from .properties file and fill them as values to .yml file. E.g.: profile: dev, or
autoAgents:
client:
id: 1
Properties from .yml file can be accessed from code same way as from .properties file.
Your problem is in way how you access properties. When you use "#Configuration properties", you have to specific which one to use (e.g. #ConfigurationProperties("autoAgents.client").

Is it possible to use values from application.properties to set field of Hibernate #Table annotation

I have a Spring, Hibernate application. I would like to set scheme property of #Table annotation like this using value from application.properties file.
#Entity
#Table(schema = "${hibernate.scheme}")
public class Holidays {
// code
}
But it does not work. Spring does not substitute ${hibernate.scheme} with property value. Is there a way to solve it?
I am trying to do this to use different scheme for tests.
You can try default_schema: ${schema} in your app.yml and in test, you can supply the value of schema in app-test.yml.

How to set the annotation properties in spring data Elasticsearch

I've a question in spring data elasticsearch.I would like to know how whether we can set the annotation values of #Document annotation from a properties file or set it dynamically.
For eg :-
#Document(indexName = "myindex",type="mytype")
public class DocumentModel {
......
}
Here,I want to set the values of this annotation from a .properties file or use some setter methods for the same instead of hard coding it. Is there any proper way to do this ? Please help!
If you're using elasticsearchTemplate, there is a simpler variant, you can do it like this:
IndexQuery indexQuery = new IndexQueryBuilder()
.withId(docModel.getId())
.withObject(docModel)
.withIndex("myindex"+docModel.getUserId()).withTypes(<type_name>).build();
the call to withIndex("...") will override whatever index name you have in the #Document annotation

How to override the Spring #PropertySource order?

The problem is that I have the database config file that has the "user" value and I am using the PropertySource and try to get that value but the SystemEnvironmentPropertySource took the priority which has the "user" value as well.
So how can I specify for the DBConfiguration class to use the database.config's user?
P.S - I can't change the config name as it is using by many applications.
#PropertySource("file:/config/database.config")
public class DBConfiguration {
#Value("${user}")
private String user;
.....
}

Categories

Resources