Is there a way to get the hibernate mapping from within my application code?
for example, for the below mapping, I want to return createdDate given created_date from my application.
<property
name="createdDate"
type="java.lang.String"
column="created_date"
length="45"
/>
You probably could do so by using Configuration to get the Property you need, for example:-
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
Property property = configuration.getClassMapping("EntityName").getProperty("createdDate");
... // use the API from Property
Here's the javadoc for Property where you can get the information you need.
Related
I having problems defining database properties in different environments. The properties file looks like this:
db.url-DEV=host1:port:con...
db.user-DEV=user1
db.url-PROD=host2:port:con...
db.user-PROD=user2
The suffixes (-DEV,-PROD) are set on server side using a system property. How may I configure my PropertyPlaceholderConfigurer to check for a system property to switch to the right configuration? There has to be a default value if a system property is not set.
I have tried something like this, but that did not work:
${#{'db.url'+${systemEnvironmentVar}}}
The PropertyConfigurer says 'property with name 'db.url'+${systemEnvironmentVar} not found.
Simply use nested expression, example from real project:
<property name="username" value="${${ENV_NAME}database.username}" />
<property name="password" value="${${ENV_NAME}database.password}" />
where ENV_NAME is system property. Note that you have to declare this variable in jvm parameters. You can also add default ENV_NAME to your properties:
ENV_NAME=dev
And configure propertyPlaceholder to override with system properties:
<property name="searchSystemEnvironment" value="true" />
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
more about this here
But you can also use spring profiles
Create two properties files dev.properties and prod.properties with content
db.url=host1:port:con...
db.user=user1
This is common Spring pattern.
I have created a spring configuration file that works well.
My next step was to separate user configuration properties from system properties.
I have decided to create additional xml file with beans that will be configured by the user.
I had problem to create few such logical beans encapsulating properties that will be used by real class beans:
I have found over the net an option to reference proprieties in such way:
UserConf.xml
<bean id="numberGuess" class="x...">
<property name="randomNumber" value="5"/>
<!-- other properties -->
</bean>
SystemConf.xml
<import resource="UserConf.xml" />
<bean id="shapeGuess" class="y...">
<property name="initialShapeSeed" value="#{ numberGuess.randomNumber }"/>
<!-- other properties -->
</bean>
But my problem is that i need x... class to be something logical that shouldn't be initialized at all, and i don't want it to disclose any info of the class hierarchy of the system since it should be only in use configuration xml file.
Solution1 is to create a Java object representing this proprieties:
public class MyProps(...)
and add a bean parent in the spring system configuration:
<bean id="MyProps" class="path to MyProps"/>
in the user side change the previous bean to be:
<bean id="numberGuess" parent="MyProps">
<property name="randomNumber" value="5"/>
<!-- other properties -->
</bean>
Solution2 is to use flat configuration file just like Database.props, and load it using factory.
Solution3 is to use Spring Property Placeholder configuration to load properties from XML properties file (e.g. example), but here i simply don't know how to get a more complex nested structure of properties (properties need to be separated by different logical names, e.g. minNumber will be defined both under xAlgo and y algo).
I don't like to create new Java class only to deal with this problem or to move my user configuration to a flat props file (i need the xml structure), is their any other solution??
I will answer my own question, since it looks as the best solution for me (and much more simplistic than was suggested)
I will use PropertiesFactoryBean to do the work for me:
e.g.
UserConf.xml
<bean id="numberGuess" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="randomNumber">3</prop>
<!-- other properties -->
</bean>
SystemConf.xml
<import resource="UserConf.xml" />
<bean id="shapeGuess" class="y...">
<property name="initialShapeSeed" value="#{ numberGuess.randomNumber }"/>
<!-- other properties -->
</bean>
First if you don't know about the property place holder you should take a look at that. Also #Value("${some.property:defaultvalue}") is something you should look at.
Second the word configuration is ambiguous in Spring. Spring uses this word but they mean developer configuration not user configuration. Despite what people say or think Spring is not a configuration engine.
I'm not sure what your trying to do but you should be aware that your configuration will not be adjusted at runtime which is frequently needed for something like "user" configuration. So most people write their own configuration layer.
Another thing you should take a look at is not using the XML configuration and instead use Java Configuration which will give you way more flexibility.
In the Spring Framework, how do you determine what "properties" and other related values are available to be set in the context.xml file(s)? For example, I need to set the isolation level of a TransactionManager. Would that be:
<property name="isolation" value="SERIALIZABLE" />
<property name="isolation_level" value="Isolation.SERIALIZABLE" />
or some other values?
Each bean represents a class, which you can easily find by class="" attribute. Now you simply open JavaDoc or source code of that class and look for all setters (methods following setFooBar() naming convention). You strip set prefix and un-capitalize the first character, making it fooBar. These are your properties.
In your particular case you are probably talking about PlatformTransactionManager and various implementations it has.
Putting the properties into . properties file is a good way of handling.
First define a properties file in your project structure. It is better to put .properties file with the same directory as spring applicationContext.xml.
Your properties file may seem like this :
isolation = "SERIALIZABLE"
isolation_level = Isolation.SERIALIZABLE
You can access this properties file by defining a spring bean like :
<bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:YourProperties.properties"/>
</bean>
Finally you can access these properties inside Spring beans like :
<bean id="BeanName" class="YourClass">
<property name="PropertyName1" value="${isolation}"/>
<property name="PropertyName" value="${isolation_level}"/>
</bean>
There is another way to inject these values using annotations.
In my spring batch project I can do something like this:
<bean id="exampleTasklet" class="my.custom.Tasklet">
<property name="message" value="job parameter value: #{jobParameters['arg1']}"/>
</bean>
and the message property will have a value taken from the spring batch job parameters. However, the value that I actually want to assign is very large and I don't want to put it in the xml file. I know this syntax doesn't work, but I would like to do something like:
<bean id="exampleTasklet" class="my.custom.Tasklet">
<property name="message" read-value-from-file="/path/to/file.txt"/>
</bean>
and that file would contain the line "job parameter value: #{jobParameters['arg1']}" which spring will parse as if the file content was in a value="" attribute.
Is there a nice way to do this?
I think what you are looking for is a PropertyPlaceholderConfigurer.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="/path/to/file.properties" />
<property name="placeholderPrefix" value="#{" />
<property name="placeholderSuffix" value="}" />
</bean>
This is run by Spring as a bean processor and will attempt to resolve placeholder tokens. There is a default instance that will resolve against system properties, using this notation: ${propertyname}. For your notation, you would need to specify the placeholderPrefix/Suffix. When there are multiple bean processors, the order is determined by the order property. By default, if a processor fails to resolve a placeholder, execution fails, but this can be altered by setting ignoreUnresolvablePlaceholders. Since the mechanism is property driven, you probably want to consider a notation like:
<property name="message" value="job parameter value: #{jobParameters.arg1}"/>
Or, if what you're trying to convey is that arg1 is also a parameter, you might try:
<property name="message" value="job parameter value: #{jobParameters.${arg1}}"/>
Spring loops over the bean processors until no replacements are performed, or an exception is raised. So defining a property as ${something.${orOther}} is valid.
I would suggest you to use a String as file name and in your bean open that file.
I'm not sure if I get your problem right. I'm just suggesting something like Spring MessageBundle
Something like this:
<bean id="exampleTasklet" class="my.custom.Tasklet">
<property name="messagePath" location="/path/to/file.txt"/>
</bean>
And in your exampleTasklet read the file and do your thing (I'm not sure what it is)
If anybody came here to do something like this from a properties-file:
If you want a property from a .properties-file to appear in the JobParameters, you won't find ready-to-use solution. You can do the following:
Wrap a bean around your properties file.
Pass this bean to another one which has access to the JobParameters and can pump the properties from the file into that class.
Then you should be able to access your properties with Spring's Expression Language and do something like:
<bean id="myBean" class="my.custom.Bean">
<property name="prop" value="#{jobParameters['arg1']}"/>
</bean>
Alternatively, I think the solution proposed by Devon_C_Miller is much easier. You don't have the properties in your JobParameters then. But if the replacement in the XML configuration is the only thing you want, you only have to change your placeholders to:
${myPropFromFile}
Happy batching, everyone ;-)
I am building a framework that manage the access to the database.
the framework getting tasks from the user and handle a connection pooling that manage the access to the database. the user just send me SQL commands.
One of the feature that i would like to support is working with JPA, in this case i will provide entity manager. in some cases i would like to provide JDBC access as well as JPA access. the arguments for the database are written in XML file.
so for JPA i need to write the property in persistence.xml so it will be not so smart to write again the same arguments for JDBC. do you know if i can get the arguments of the database from persistence.xml, do you know if there is a source code that do it. or should i parse persistence.xml by myself?
Do you know if I can get the arguments of the database from persistence.xml, do you know if there is a source code that do it. Or should I parse persistence.xml by myself?
I'm not aware of anything in the standard JPA API allowing to retrieve the driver class name, the jdbc url, the username and password.
Second problem, the keys for those properties are not standardized in JPA 1.0. For example, Hibernate will use:
<property name="hibernate.connection.driver_class" value=""/>
<property name="hibernate.connection.url" value=""/>
<property name="hibernate.connection.username" value=""/>
<property name="hibernate.connection.password" value=""/>
While EclipseLink will use:
<property name="eclipselink.jdbc.driver" value=""/>
<property name="eclipselink.jdbc.url" value=""/>
<property name="eclipselink.jdbc.user" value=""/>
<property name="eclipselink.jdbc.password" value=""/>
This may make the parsing fragile.
If this is an option, maybe you could use a properties file to store both the provider specific keys and the values (I'd recommend using the standardized JPA 2.0 properties as keys). For example:
# keys for JPA
javax.persistence.jdbc.driver = hibernate.connection.driver_class
javax.persistence.jdbc.url = hibernate.connection.url
javax.persistence.jdbc.user = hibernate.connection.username
javax.persistence.jdbc.password = hibernate.connection.password
# values common to JPA and JDBC
driver = org.h2.Driver
url = jdbc:h2:mem:test
username = scott
password = tiger
And use Persistence.createEntityManagerFactory(String, Map) and pass a Map that you'll feed with the properties from the file to create the EntityManagerFactory:
Map map = new HashMap();
map.put(...);
...
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPu", map);