I have a source tree composed of source and test classes. When I run the tests, I'd like to use <property name="hbm2ddl.auto">create</property> while when running the code I'd like to use a validate value instead of create.
I thought to use two config files, one with all the properties and containing hbm2ddl.auto set to validate, and another with hbm2ddl.auto set to create. I hoped that the following code would have allowed me to read from the tests the basic file and override the only hbm2ddl.auto propery, but it doesn't work (the value of hbm2ddl.auto is still the one read from hibernate.cfg.xml.
Configuration configuration = new Configuration();
configuration = configuration.
configure("hibernate.cfg.xml").
addResource("hibernate-test.cfg.xml");
How can I have two different values for a property, without replicating the whole config file?
It seems to me that when you have only a few values to override, one simple approach is to load the xml config as usual, and then call setProperty programmatically, like this:
Configuration configuration = new Configuration();
configuration = configuration.configure("hibernate.cfg.xml");
configuration.setProperty("hibernate.hbm2ddl.auto", "create-drop");
hbm.xml files don't allow to override values with addResource(...) as I tried to do, the values are only added and not overridden
I had that problem with trying to programmatically load another config. Work around i used was to have another hibernate.properties file (instead of xml config). You can set the alternate hibm2ddl value in this properties file and load it using following code:
Properties props = new Properties();
props.load(new FileInputStream(propFile));
configuration = new Configuration().setProperties(props);
Try and see if this works for you.
Imp: don't call configuration.configure().
Related
I want to create a MysqlConnectionPoolDataSource, but I am not sure which setter methods (setURL, setPort, setPropertiesViaRef, etc) are optional and which are required when configuring the DataSource object. Do I need to configure all of those methods, or only a few of them?
It depends on the configuration you would like to set however, the following parameters should be sufficient in most of the cases:
MysqlConnectionPoolDataSource poolDataSource = new MysqlConnectionPoolDataSource();
poolDataSource.setUser("yourUsername");
poolDataSource.setPassword("yourPassword");
poolDataSource.setServerName("yourServersIP");
poolDataSource.setPort(3306);
poolDataSource.setDatabaseName("yourDBName");
I have a Spring 3.1 application. Let's say it has an XML with the following content:
<context:property-placeholder location="classpath:somename.properties" />
<context:property-placeholder location="classpath:xxx.properties" />
I would like some.properties to be always loaded (let's assume it exists), but the xxx part of the second place holder to be replaced by some name depending on the active profile. I've tried with this:
<beans profile="xx1">
<context:property-placeholder location="classpath:xx1.properties" />
</beans>
<beans profile="xx2">
<context:property-placeholder location="classpath:xx2.properties" />
</beans>
Also, both files have properties with the same key but different value.
But it didn't work as some later bean that has a placeholder for one property whose key is defined in xx1.properties (and xx2.properties) makes Spring complain that the key is not found in the application context.
You can do:
<context:property-placeholder location="classpath:${spring.profiles.active}.properties" />
It works fine, but is perhaps not adapted when using multiple profiles in the same time.
When declaring 2 property placeholders, if the 1st one does not contain all the applications keys, you should put the attribute ignoring unresolvable = true, so that the 2nd placeholder can be used.
I'm not sure if it is what you want to do, it may if you want both xx1 and xx2 profiles be active in the same time.
Note that declaring 2 propertyplaceholders like that make them independant, and in the declaration of xx2.properties, you can't reuse the values of xx1.properties.
If you need something more advanced, you can register your PropertySources on application startup.
web.xml
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.xxx.core.spring.properties.PropertySourcesApplicationContextInitializer</param-value>
</context-param>
file you create:
public class PropertySourcesApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static final Logger LOGGER = LoggerFactory.getLogger(PropertySourcesApplicationContextInitializer.class);
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
LOGGER.info("Adding some additional property sources");
String profile = System.getProperty("spring.profiles.active");
// ... Add property sources according to selected spring profile
// (note there already are some property sources registered, system properties etc)
applicationContext.getEnvironment().getPropertySources().addLast(myPropertySource);
}
}
Once you've done it you just need to add in your context:
<context:property-placeholder/>
Imho it's the best way to deal with spring properties, because you do not declare local properties everywhere anymore, you have a programmatic control of what is happening, and property source xx1 values can be used in xx2.properties.
At work we are using it and it works nicely. We register 3 additional property sources:
- Infrastructure: provided by Puppet
- Profile: a different property loaded according to the profile.
- Common: contains values as default, when all profiles share the same value etc...
I have decided to submit and answer to this as it has not yet been accepted. It may not be what you are looking for specifically but it works for me. Also note that i am using the new annotation driven configuration however it can be ported to the xml config.
I have a properties file for each environment(dev.properties, test.properties etc)
I then have a RootConfig class that is the class that is used for all the configuration. All that this class has in it is two annotations: #Configuration and #ComponentScan(basePackageClasses=RootConfig.class).
This tells it to scan for anything in the same package as it.
There is then a Configuration Containing all my normal configuration sitting wherever. There is also a configuration for each environment in the same package as the root configuration class above.
The environment specific configurations are simply marker classes that have the following annotations to point it to the environment specific properties files:
#Configuration
#PropertySource("classpath:dev.properties")
#Import(NormalConfig.class)
#Profile("dev")
The import tells it to bring in the normal config class. But when it gets in there it will have the environment specific properties set.
I have few properties in my Properties file like
dataCenterOptions.host="xyz"
dataCenterOptions.user="abc"
dataCenterOptions.password="def"
dataCenterOptions.port="ghi"
I'm using this is in my Spring class by annotating it with #Value. However instead of creating four separate variables can I have a single variable to access each of the following variables. Something like
#Value("${dataCenterOptions}")
Properties dataCenterProps;
How do I do this?
Oneway is
At code
#Resource(name="prop")
Properties prop;
At config file
<util:properties id="prop" location="properties/dataCenterOptions.properties" />
Quartz is usually configured via quartz.properties on the classpath.
e.g.:
org.quartz.scheduler.instanceName = BagginsScheduler
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=5
org.quartz.threadPool.threadPriority=1
From within the same application that will run the Quartz jobs, I'd like to read out the properties.
Reading the scheduler name is easy:
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
String name = scheduler.getSchedulerName();
But how can I read the `threadPriority' property?
The following does not work:
scheduler.getContext().getString("org.quartz.threadPool.threadPriority");
UPDATED Solution:
It seems that the property can't be read via Quartz API, you have to go via regular Properties:
Properties prop = new Properties();
prop.load(AnyClassUsedByJVM.class.getClassLoader().getResourceAsStream("quartz.properties"));
String prio = prop.getProperty("org.quartz.threadPool.threadPriority");
This works fine.
You can just add that property to your quartz.properties. For example:
org.quartz.threadPool.threadPriority=3
For more information, see here and configuration documentation
EDIT: To read properties at runtime, you can use Properties. Here's a sample snippet of code you can use:
Properties p = new Properties();
p.load("/tmp/quartz.properties"); // path to your properties file
System.out.println(p.getProperty("org.quartz.threadPool.threadPriority"); // prints 3
I'm trying to change cfg properties at runtime.
For example:
cfg.setProperty("hibernate.connection.url")
The problem is that it works only when this property is not defined in the cfg file itself,
meaning, it doesn't override.
Can it be done in some way?
when you run
Configuration cfg = new Configuration().configure();
the .configure() reads the data from the XML, and it has a higher priority over the programmatic configuration.
However, if you remove the .configure, all the configuration will be "read" from the settings that you will pass. For example:
Configuration configuration = new Configuration()
.setProperty( "hibernate.connection.driver_class", "org.postgresql.Driver" )
.setProperty( "hibernate.dialect","org.hibernate.dialect.PostgreSQLDialect")
[...snip...]
.addAnnotatedClass( com.myPackage.MyClass.class )
[...] ;
will set all the properties at runtime.