Spring MBeanExporter - giving name to MBean - spring

I'm trying to run a simple application with jmx-exported method. I do it like (spring-context and cglib for "#Configuration" are in classpath):
package com.sopovs.moradanen.jmx;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jmx.export.MBeanExporter;
import org.springframework.stereotype.Component;
#Component
#Configuration
public class SpringJmxTest {
public static void main(String[] args) {
new AnnotationConfigApplicationContext("com.sopovs.moradanen.jmx");
while (true) {
Thread.yield();
}
}
#Bean
public MBeanExporter createJmxExporter() {
return new MBeanExporter();
}
public interface FooBarMBean {
public String hello();
}
#Component
public static class FooBar implements FooBarMBean {
#Override
public String hello() {
return "Hello";
}
}
}
However when I run it I get:javax.management.MalformedObjectNameException: Key properties cannot be empty. I tried to debug and solved it with:
#Component
public static class FooBar implements FooBarMBean, SelfNaming {
#Override
public String hello() {
return "Hello";
}
#Override
public ObjectName getObjectName() throws MalformedObjectNameException {
return new ObjectName("fooBar:name=" + getClass().getName());
}
}
But is there a better way to supply a name for MBean?

You can use the descriptions annotations provided by Spring Context #Managed* :
To do this, you must NOT implements the interface with "MBean" or "MXBean" suffix, neither SelfNaming.
Then, the bean will be detected as a standard spring "managed bean" when MBeanExporter will registerBeanInstance(..), and will be converted to a ModelMBean using all spring annotations, including descriptions of attributes, operations, parameters, etc..
As a requirement, you should declare in your spring context the MBeanExporter with AnnotationJmxAttributeSource, MetadataNamingStrategy, and MetadataMBeanInfoAssembler attributes, which can be simplified like this (as described here):
<bean id="mbeanExporter"
class="org.springframework.jmx.export.annotation.AnnotationMBeanExporter" />
or:
<context:mbean-export />
or, using programmatic approach:
#Configuration
#EnableMBeanExport
public class AppConfig {
}
And your managed bean should look like this :
#Component("myManagedBean")
#ManagedResource(objectName="your.domain.jmx:name=MyMBean",
description="My MBean goal")
public class AnnotationTestBean {
private int age;
#ManagedAttribute(description="The age attribute", currencyTimeLimit=15)
public int getAge() {
return age;
}
#ManagedOperation(description = "Check permissions for the given activity")
#ManagedOperationParameters( {
#ManagedOperationParameter(name = "activity",
description = "The activity to check")
})
public boolean isAllowedTo(final String activity) {
// impl
}
}
Remember to not implements an MBean interface, which would be a StandardMBean, and SelfNaming interface, which would bypass Spring naming management !

You can use KeyNamingStrategy to define all JMX-related properties inside XML configuration without adding any compile-time dependencies to Spring into the source code of your MBean:
<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="namingStrategy" ref="namingStrategy"/>
</bean>
<bean id="namingStrategy"
class="org.springframework.jmx.export.naming.KeyNamingStrategy">
<property name="mappings">
<props>
<prop key="someSpringBean">desired.packageName:name=desiredBeanName</prop>
</props>
</property>
</bean>
If you can live with somewhat arbitrary object names, then you can use the IdentityNamingStrategy as a naming strategy for MBeanExporter and minimize the XML configuration event further:
<bean class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
<property name="namingStrategy" ref="namingStrategy"/>
</bean>
<bean id="namingStrategy"
class="org.springframework.jmx.export.naming.IdentityNamingStrategy"/>

Check spring documentation: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/jmx.html section 22.3.2 explains the JDK 5.0 annotations that are available.
Section 22.4 explains mechanisms available for object naming.

Related

SimpleRabbitListenerContainerFactory.setAdviceChain: can MethodInterceptor accept POJO that parameterizes #RabbitListener?

Versions:
org.springframework.amqp:spring-rabbit:2.4.8
openjdk version "11.0.12" 2021-07-20
XML:
<bean id="myAdvice" class="com.acme.interceptors.TrackNewBarcode"/>
<bean id="rmqMessageConverter" class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter">
<constructor-arg ref="myObjectMapper"/>
</bean>
<bean id="rabbitListenerContainerFactory" class="org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="concurrentConsumers" value="1"/>
<property name="maxConcurrentConsumers" value="1"/>
<property name="receiveTimeout" value="316224000000"/>
<property name="messageConverter" ref="rmqMessageConverter"/>
<property name="adviceChain" ref="myAdvice"/>
</bean>
Java:
package com.acme.tasks;
import com.acme.io.NewBarcodes;
import javax.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
#Validated
#Component
public class ConsumeBarcodes
{
private static final Logger logger = LoggerFactory.getLogger(ConsumeBarcodes.class);
#Value("${rabbitmq.queue}")
private String queueName;
public ConsumeBarcodes() {}
#RabbitListener(queues = "${rabbitmq.queue}", ackMode = "AUTO")
public void ingestNewBarcodes(#NotNull NewBarcodes newBarcodes)
{
logger.debug("RECEIVED message in ingestNewBarcodes from RabbitMQ queue: {}", queueName);
// XXX Process newBarcodes here.
}
}
Advice:
package com.acme.interceptors;
...
public class TrackNewBarcode implements MethodInterceptor
{
...
#Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable
{
NewBarcodes newBarcodes = (NewBarcodes)methodInvocation.getArguments()[1];
...
}
}
In the examples I have seen for #RabbitListener advices, in invoke(), argument #1 is cast to a Message. But in my #RabbitListener, I rely on a Jackson message-converter to convert the inbound parameter into the POJO NewBarcodes.
QUESTION: in my advice here, can I cast argument #1 to the POJO NewBarcodes?
The simple answer is No. methodInvocation.getArguments() returns a Channel in the first argument (index 0), and a Message in the second argument (index 1). Casting a Message to NewBarcodes would lead to an exception.
Nevertheless, there are still other ways to encode an advice here. I spell out one approach below.
First, per Spring AOP docs, you should enable AOP functionality in your application configuration. Eg:
#Configuration
#EnableAspectJAutoProxy
public class MyWebAppConfig implements WebMvcConfigurer
{
...
}
Annotate ConsumeBarcodes with #Aspect, and set up #Pointcut and #After advice:
#Aspect
#Validated
#Component
public class ConsumeBarcodes
{
private static final Logger logger = LoggerFactory.getLogger(ConsumeBarcodes.class);
#Value("${rabbitmq.queue}")
private String queueName;
public ConsumeBarcodes() {}
#RabbitListener(queues = "${rabbitmq.queue}", ackMode = "AUTO")
public void ingestNewBarcodes(#NotNull NewBarcodes newBarcodes)
{
logger.debug("RECEIVED message in ingestNewBarcodes from RabbitMQ queue: {}", queueName);
// XXX Process newBarcodes here.
}
#Pointcut("execution(com.acme.tasks.ConsumeBarcodes.ingestNewBarcodes(..)")
public void newBarcodesIn() {}
#After("newBarcodesIn()")
public void ackNewBarcodesIn(JoinPoint jp)
{
NewBarcodes newBarcodes = (NewBarcodes)jp.getArgs()[0];
...
}
}
Arguably, this is overkill, as we could simply put logic from ackNewBarcodesIn() inside ingestNewBarcodes() and forgo advices altogether. Nevertheless, I have confirmed this setup works and the #After advice fires as expected.

Spring: Autowired is null in ejb class

I have the following situation:
#Controller
public class myController {
#Autowired
private IProxy service;
public ModelAndView init(HttpServletRequest request, HttpServletResponse response) throws Exception {
List<String> list = service.getName();
}
}
Then my Service is define as follow:
public interface IProxy {
public List<String> getName();
}
Proxy class is responsible for the lookup to the remote bean
#Service("service")
public class Proxy implements IProxy {
...
public List<String> getName() {
return myClass.getName();
}
And the implementation is the following:
#Interceptors(interceptor.class)
#Stateless
#Resource(name = "java:/db")
#Remote(MyClassRemote.class)
public class MyClassImpl extends MyEjb implements MyClassRemote{
#PersistenceContext(unitName = "db")
private EntityManager em;
#Resource
private SessionContext sctx;
#Autowired
public IMyRepo myRepo;
#Override
public List<String> getName() {
try {
return myRepo.getName(em);
}
catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
finally {}
}
So, the problem is that here myRepo is null. I don't know why because IMyRepo and his implementation are always located within the path scanned by Spring.
Just one clarification: MyRepo class that implements IMyRepo is annotated with #Repository.
Any idea?
you can inject spring beans in EJB using Spring interceptors, as explained here in the official documentation. Basically you'll need to adjust your class as follows:
// added the SpringBeanAutowiringInterceptor class
#Interceptors({ interceptor.class, SpringBeanAutowiringInterceptor.class })
#Stateless
#Resource(name = "java:/db")
#Remote(MyClassRemote.class)
public class MyClassImpl extends MyEjb implements MyClassRemote{
// your code
}
You'll also need to define the context location in a beanRefContext.xml file (with your own application context file):
application-context.xml version
<bean id="context"
class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg>
<list>
<value>application-context.xml</value>
</list>
</constructor-arg>
</bean>
Java Configuration version:
<bean id="context"
class="org.springframework.context.annotation.AnnotationConfigApplicationContext">
<constructor-arg>
<list>
<value type="java.lang.Class">com.your.app.Configuration</value>
</list>
</constructor-arg>
</bean>
Spring beans and EJB are two different things, you can't just inject a Spring bean in an EJB, because that EJB is no Spring bean, so Spring doesn't know there is a field which should be injected by Spring (unless you use some fancy AOP stuff, which can enable injection into non-Spring-managed beans).

How can we switch between different Implementations in Spring Context XML with an Boolean?

How can we switch between different Implementations in Spring Context XML with an Boolean?
for example:
<bean id="detailsController" class="com.something.detailsController" >
if true then
<property name="dao" ref="firstDao"/>
else
<property name="dao" ref="secoundDao"/>
I know in Spring3 we can work with profiles
You could do that by modifying your Java code and use Spring EL together with ApplicationAware and InitializingBean.
public class DetailsController implements ApplicationContextAware, InitializingBean {
private DetailsControllerDAO dao;
private String daoName;
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public void afterPropertiesSet() {
dao = applicationContext.getBean(daoName);
}
public void setDaoName(String daoName) {
this.daoName = daoName;
}
}
In XML:
<bean id="detailsController" class="com.something.detailsController">
<property name="daoName" value="#{myCondition ? 'firstDao' : 'secondDao'}" />
</bean>
Of course, this solution has the disadvantage to add dependency to Spring code in your controller. To avoid that, you could move that code in a proxy class, as described by Guillaume Darmont.
I dont think this can be done at the XML level.
Spring really cannot do that. See the bean lifecycle. Been classes are created, than properties are injected and than afterPropertiesSet() or #PostConstructor methods are invoked. Of course when I omit lazy initialized beans.
But if you want for testing etc. and so you need just the firstDao or the secondDao in your application at the sametime that depends just on your settings, you can use a bean factory. The bean factory creates your bean as you want. I also use it for to split development environment, test environment and production environment.
package com.dummyexample.config;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Factory bean to create real or test dao.
* The result depends on realDaoEnabled configuration parameter.
*
* #author Martin Strejc
*/
#Configuration
public class DaoBeanFactory {
// mapping to servlet context configuration
#Resource(mappedName = "realDaoEnabled")
private Boolean realDaoEnabled = true;
// TestDao extends or implements Dao
#Autowired
private TestDao testDao;
// ProdDao extends or implements Dao
#Autowired
private ProdDao prodDao;
public DaoBeanFactory() {
}
#Bean(name="dao")
public Dao getDao() {
if(realDaoEnabled) {
return prodDao;
}
return testDao;
}
}
Since your DAOs are exchangeable, they inherits the same type (abstract class or interface). Thus you can write a RoutingDetailsControllerDAO.
Let's say that your common interface is named DetailsControllerDAO, with two methods getDetails and getMoreDetails inside, the code would be :
public class RoutingDetailsControllerDAO implements DetailsControllerDAO {
private DetailsControllerDAO firstDAO;
private DetailsControllerDAO secondDAO;
protected DetailsControllerDAO getDAOToUse() {
return YOUR_BOOLEAN_CONDITION ? firstDAO : secondDAO;
}
#Override
public Details getDetails() {
return getDAOToUse().getDetails();
}
#Override
public Details getMoreDetails() {
return getDAOToUse().getMoreDetails();
}
// Insert firstDAO and secondDAO setters below
...
}
Your Spring XML config is now :
<bean id="detailsController" class="com.something.detailsController" >
<property name="dao" ref="routingDetailsControllerDAO"/>
</bean>
<bean id="routingDetailsControllerDAO" class="com.something.RoutingDetailsControllerDAO">
<property name="firstDao" ref="firstDao"/>
<property name="secondDao" ref="secondDao"/>
</bean>
Few possibilities:
You can either use profiles (<beans profiles="profileOne">).
You can use FactoryBean to create the correct DAO
You can use SPeL
The last one is the easiest:
<bean id="detailsController" class="com.something.detailsController">
<property name="dao" ref="#{condition ? 'firstDao' : 'secondDao'}" />
</bean>
Of course you can load bean name from properties file via property configurer:
<bean id="detailsController" class="com.something.detailsController">
<property name="dao" ref="${bean.name.from.properties.file}" />
</bean>

autowiring byName in spring

I am just starting up with Spring and trying autowiring byName
here is my code
Address class:
package org.springinaction;
public class Address {
private String addressline;
public String getAddressline() {
return addressline;
}
public void setAddressline(String addressline) {
this.addressline = addressline;
}
}
Customer class:
package org.springinaction;
public class Customer {
private Address address;
public Address getN() {
return address;
}
public void setN(Address n) {
this.address = n;
}
}
Spring cofiguration:
<beans>
<bean id="customer" class="org.springinaction.Customer" autowire="byName" />
<bean id="address" class="org.springinaction.Address">
<property name="addressline" value="bangalore" />
</bean>
</beans>
CustomerTest.java
package org.springinaction;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class CustomerTest {
public static void main(String[] args) {
ApplicationContext context =new ClassPathXmlApplicationContext("SpringInAction.xml");
Customer cust=(Customer)context.getBean("customer");
System.out.println(cust.getN());
}
}
When I am trying to do autowring by name which states thats if name of property matches with name of name it will get autowired.however in my case its not happening.
its giving me null with this...can anyone help me this this so that it be autowired correctly
The "name" that auto wiring looks for is the name of the JavaBean property as derived from the name of the setter method, therefore your Customer class has a property named n (from the setN method), the fact that the private field is named address is irrelevant.
You either need to define a suitable bean with id n or change the getter and setter in Customer to getAddress and setAddress in order to match the name of the existing address bean.
Change your getter and setter to this:
public Address getAddress() {
return address;
}
public void setAddress(Address n) {
this.address = n;
}
According to Java beans convention your getter and setter must have name get (or set) + name of property with first letter capitalized.
If you just want your Customer bean to be injected with your Address bean, then simply use the #Autowired annotation, no need for setters/getters then:
<context:annotation-config /> // EDIT - think this required for autowiring
<bean id="customer" class="org.springinaction.Customer"/>
<bean id="address" class="org.springinaction.Address">
<property name="addressline" value="bangalore" />
</bean>
public class Customer {
#Autowired
Address address;
....
Have more than 1 address bean? Then use the #Qualifier as well:
<bean id="customer" class="org.springinaction.Customer"/>
<bean id="work-address" class="org.springinaction.Address">
<property name="addressline" value="bangalore" />
</bean>
<bean id="home-address" class="org.springinaction.Address">
<property name="addressline" value="bangalore" />
</bean>
public class Customer {
#Autowired
#Qualifier ( value = "work-address" )
Address workAddress;
#Autowired
#Qualifier ( value = "home-address" )
Address homeAddress;
....

Spring #Autowired not working

I have some problems wth autowire annotation. My app looks like this:
Here is controller:
#Controller
public class MyController {
#Autowired
#Qualifier("someService")
private SomeService someService;
....
}
It's a service layer:
public interface SomeService {
...
}
#Service
public class SomeServiceImpl implements SomeService{
#Autowired
#Qualifier("myDAO")
private MyDAO myDAO;
....
}
And DAO layer:
public interface MyDAO{
....
}
#Repository
public class JDBCDAOImpl implements MyDAO {
#Autowired
#Qualifier("dataSource")
private DataSource dataSource;
....
}
This is a app-service.xml file:
....
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
<bean id="SomeService" class="com.service.SomeServiceImpl" />
<bean id="myDAO" class="com.db.JDBCDAOImpl" />
So... When I'm launching a web-app, MyController Autowires correctly (the someService field correctly injected by SomeServiceImpl class object), but myDAO feild of someService has null value (not injected properly).
Could you help me to find a problem?
P.S. Its interesting, but when I'm changing a "bean id" from myDAO to some another (e.g. myDAO2), system gives me an error, that injecting could not be done, because bean myDAO doesn't exist. So, Spring make an injection, but where it is? And why it's not work correctly?
I found the solution. As Javi said (thanks a lot for you, Javi), I have to annotate DAO and Service layer classes with #Repository and #Service annotation. Now I've tried to write like this:
#Service("someService")
public class SomeServiceImpl implements SomeService{
#Autowired
#Qualifier("myDAO")
private MyDAO myDAO;
....
}
and
#Repository("myDAO")
public class JDBCDAOImpl implements MyDAO {
#Autowired
#Qualifier("dataSource")
private DataSource dataSource;
....
}
and all works fine!!!
But I still not found an answer for this quesion: if application will be more complex, and will have more complex structure, where #Repositore and #Service annotation are not preferred for some classes, how to inject correctly beans, which located in lower levels (in a fields of classes, or in a field of fields of classes) (with #Autowire annotation, of course)?
I guess you need <context:annotation-config />.
You can use
<context:component-scan base-package="PATH OF THE BASE PACKAGE"/>
entry in your configuration .xml file. This entry will scan/read all the stated type and annotations from the java classes.
Important points:
Sometimes, #Component may leads to a problem where it might say no default constructor found.
The class which is defined as a #Component annotation, it must have a default constructor.
Suppose, we have applied #Autowired annotation at field which is a user defined class reference.
Now, if we also apply #Component to that class then it will always be initialized with null.
So, a field with #Autowired should not have #Component at its class definition.
By default #Autowired is byType.
Address bean is autowired at Student class.
Let’s see what happens if we apply #Component at Address.java.
CollegeApp.java:
package com.myTest
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.bean.Address;
import com.bean.Student;
//Component scanning will for only those classes
//which is defined as #Component. But, all the class should not use
//#Component always even if the class is enabled with auto
//component scanning, specially the class which is Autowired
//Or which is a property of another class
#Configuration
#ComponentScan(basePackages={"com.bean"})
public class CollegeApp {
#Bean
public Address getAddress(){
return new Address("Elgin street");
}
public static void main(String[] args) {
AnnotationConfigApplicationContext context=new AnnotationConfigApplicationContext(CollegeApp.class);
Student student=context.getBean(Student.class);
System.out.println(student.toString());
context.close();
}
}
We want Elgin street to be autowired with Student address.
Address.java:
package com.bean;
import org.springframework.stereotype.Component;
#Component
public class Address {
private String street;
public Address()
{
}
public Address(String theStreet)
{
street=theStreet;
}
public String toString()
{
return (" Address:"+street);
}
}
Student.java:
package com.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class Student {
private String name;
private int age;
private Address address;
public Student()
{
}
public Student(String theName,int theAge)
{
name=theName;age=theAge;
}
#Autowired
public void setAddress(Address address) {
this.address = address;
}
public String toString()
{
return ("Name:"+name+" Age:"+age+ " "+address);
}
}
Output: - Name:null Age:0 Address:null //Address not Autowired here.
To resolve the issue, only change the Address.java as below:
Address.java:
package com.bean;
public class Address {
private String street;
public Address(String theStreet)
{
street=theStreet;
}
public String toString()
{
return (" Address:"+street);
}
}
Output:-
Name:null Age:0 Address:Elgin street
You should include this section of XML code in spring-config.xml :
<context:component-scan base-package="Fully.Qualified.Package.Name" />
but you should know the difference between <context:annotation-config> vs <context:component-scan> as most people are suggesting these two :
1) First big difference between both tags is that <context:annotation-config> is used to activate applied annotations in already registered beans in application context. Note that it simply does not matter whether bean was registered by which mechanism e.g. using <context:component-scan> or it was defined in application-context.xml file itself.
2) Second difference is driven from first difference itself. It does register the beans in context + it also scans the annotations inside beans and activate them. So <context:component-scan>; does what <context:annotation-config> does, but additionally it scan the packages and register the beans in application context.
There can be two reasons for this.
When you have not annotated the injected object or say service with proper #Service/#Component/#Repository annotations.
Once you have made sure of point 1 ,next check for whether the class package of your annotated service class is included in the class-path for your spring boot application in the main class.You can configure this using the following annotation.
#SpringBootApplication(scanBasePackages = {
"com.ie.efgh.somepackage","com.ie.abcd.someotherpackage" })
Doing this you tell spring to look into the packages for the classes during class loading.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Specifying base package of the Components like Controller, Service,
DAO -->
<context:component-scan base-package="com.jwt" />
<!-- Getting Database properties -->
<context:property-placeholder location="classpath:application.properties" />
<!-- DataSource -->
<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource"
id="dataSource">
<property name="driverClassName" value="${database.driver}"></property>
<property name="url" value="${database.url}"></property>
<property name="username" value="${database.user}"></property>
<property name="password" value="${database.password}"></property>
</bean>
<!-- Hibernate SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
</bean>
</beans>

Resources