Adding TransactionManager in Hibernate Spring - java

Getting error when adding Transaction-Manager. What's wrong? :/
Few possible answers reffer to lack of some hibernate libraries. However It seems that all of them do persist. How to overcome this?
Also I want to add some test data to my database. In what class is it better to insert it?
Thank you.
ERROR:
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception
parsing XML document from ServletContext resource [/WEB-INF/dispatcher-servlet.xml]; nested
exception is java.lang.NoClassDefFoundError: org/aopalliance/intercept/MethodInterceptor
Dispatcher-Servlet:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="miniVLE.controller" />
<context:component-scan base-package="miniVLE.service" />
<context:component-scan base-package="miniVLE.beans" />
<context:component-scan base-package="miniVLE.dao" />
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
<!-- Declare a view resolver-->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
<!-- Connects to the database based on the jdbc properties information-->
<bean id="dataSource" class ="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name ="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name ="url" value="jdbc:derby://localhost:1527/minivledb"/>
<property name ="username" value="root"/>
<property name ="password" value="123" />
</bean>
<!-- Declares hibernate object -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect"> ${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
</props>
</property>
<!-- A list of all the annotated bean files, which are mapped with database tables-->
<property name="annotatedClasses">
<list>
<value> miniVLE.beans.Course </value>
<value> miniVLE.beans.Student </value>
<value> miniVLE.beans.Department </value>
<value> miniVLE.beans.Module </value>
<value> miniVLE.beans.TimeSlot </value>
</list>
</property>
</bean>
<!-- Declare a transaction manager-->
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
DAO:
#Repository
public class MiniVLEDAOImplementation implements MiniVLEDAO{
// Used for communicating with the database
#Autowired
private SessionFactory sessionFactory;
#Override
public void addStudentToDB(Student student) {
sessionFactory.getCurrentSession().saveOrUpdate(student);
}....
Service:
#Service
#Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class StudentService implements IStudentService{
#Autowired
MiniVLEDAOImplementation dao;
public StudentService() {
System.out.println("*** StudentService instantiated");
}
#Override
public Student getStudent(String urn){
Student s = dao.getStudentFromDB(urn);
return s;
}
#Override
#Transactional(propagation = Propagation.REQUIRED, readOnly = false)
public void addStudent(Student student) {
dao.addStudentToDB(student);
}...
Controller:
#Controller
public class miniVLEController {
#Autowired
StudentService studentService;
After adding the aopalliance-1.0.jar getting next
ERROR:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'miniVLEController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: miniVLE.service.StudentService miniVLE.controller.miniVLEController.studentService; nested exception is java.lang.IllegalArgumentException: Can not set miniVLE.service.StudentService field miniVLE.controller.miniVLEController.studentService to sun.proxy.$Proxy536
One of the solutions was to add <aop:aspectj-autoproxy proxy-target-class="true"/>into the dispatcher-servlet.
next Error:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'miniVLEController' defined in file
[C:\Users\1\Documents\NetBeansProjects\com3014_mini_VLE\build\web\WEB-
INF\classes\miniVLE\controller\miniVLEController.class]: BeanPostProcessor before
instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError:
org/aspectj/lang/annotation/Aspect

You need to add aopalliance.jar dependency.
If you use maven:
<dependency>
<groupId>aopalliance</groupId>
<artifactId>aopalliance</artifactId>
<version>1.0</version>
</dependency>

Following the problem escalation:
Needed to find aspectjrt-1.x.x.jar that was missing to overcome last error and then to overcome org.aspectj.util.PartialOrder.PartialComparable error you need to get aspectjtools-1.X.X.jar
here I found all extra libraries i needed
http://www.jarfinder.com/index.php/java/info/org.aspectj.lang.NoAspectBoundException

Related

Spring Security Issue creating bean

With Spring Security I'm trying to create the following authentication verification using Spring.
#Service("LoginUserDetailsServiceImpl")
public class LoginUserDetailsServiceImpl implements UserDetailsService {
private static final Logger logger = Logger.getLogger(UserDetailsService.class);
#Autowired
private CustomerDao customerDao;
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
logger.info("Customer DAO Email:" +email);
Customer customer = customerDao.getCustomer(email);
logger.info("Customer DAO Email:" +customer.getEmail());
Roles role = customer.getRole();
logger.info("Customer DAO Role:" + role.getRoles());
MyUserPrincipalimpl principal = new MyUserPrincipalimpl(customer);
logger.info("customerUserDetails DAO:" +principal);
if (customer == null) {
throw new UsernameNotFoundException(email);
}
return principal;
}
}
Which produces the following error
5:56,638 WARN XmlWebApplicationContext:487 - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'LoginUserDetailsServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.emusicstore.dao.CustomerDao com.emusicstore.serviceImpl.LoginUserDetailsServiceImpl.customerDao; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emusicstore.dao.CustomerDao] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
I've found if I comment out the following
<bean id="LoginUserDetailsServiceImpl" class="com.emusicstore.serviceImpl.LoginUserDetailsServiceImpl"/>
from my application-security.xml the above error is not produced. Also my junit test will execute with no issue.
#Autowired
CustomerDao customerDao;
#Test
public void LoginService() {
String email="customeremail";
logger.info("Customer DAO Email:" +email);
Customer customer = customerDao.getCustomer(email);
logger.info("Customer DAO Email:" +customer.getEmail());
Roles role = customer.getRole();
logger.info("Customer DAO Role:" + role.getRoles());
}
Repo
#Repository
public class CustomerDaoImp implements CustomerDao {
private static final Logger logger = Logger.getLogger(CustomerDaoImp.class);
#Autowired
SessionFactory sessionFactory;
Application-security.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:webflow-config="http://www.springframework.org/schema/webflow-config"
xsi:schemaLocation=" http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- <bean id="LoginUserDetailsServiceImpl" class="com.emusicstore.serviceImpl.LoginUserDetailsServiceImpl"/>-->
<security:http auto-config="true" use-expressions="true">
<security:intercept-url pattern="/login_test" access="permitAll" />
<security:intercept-url pattern="/logout" access="permitAll" />
<security:intercept-url pattern="/accessdenied" access="permitAll" />
<security:intercept-url pattern="/productList" access="permitAll" />
<!-- <security:intercept-url pattern="/**" access="permitAll" /> -->
<security:intercept-url pattern="/admin/**" access="hasRole('ROLE_ADMIN')" />
<security:intercept-url pattern="/shoppingCart/checkOut" access="hasRole('ROLE_USER')" />
<security:form-login login-page="/login_test" login-processing-url="/j_spring_security_check" authentication-failure-url="/accessdenied"
/>
<security:logout logout-success-url="/logout" />
</security:http>
<!-- <security:authentication-manager>-
<security:authentication-provider user-service-ref="LoginUserDetailsServiceImpl"/>
</security:authentication-manager> -->
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider>
<security:user-service>
<security:user name="lokesh" password="password" authorities="ROLE_USER" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mydb" />
<property name="username" value="root" />
<property name="password" value="t3l3com" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.emusicstore</value>
</list>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="1024000" />
</bean>
</beans>
Spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<mvc:annotation-driven></mvc:annotation-driven>
<context:component-scan base-package="com.emusicstore"></context:component-scan>
<bean id="viewresolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- setting maximum upload size -->
<property name="maxUploadSize" value="10000000" />
</bean>
<mvc:resources location="/WEB-INF/resource/" mapping="/resource/**"></mvc:resources>
<tx:annotation-driven />
</beans>
I'm not sure where exactly the issue is but I'm guessing it is in how the bean is configured in the xml. Should I reference the customerDao bean when in my xml file? I would have thought the #Autowired annotation would have resolved this however?
UPDATE
If I update the application-security to add a new Customer Dao bean a new error message is thrown.
<bean id="LoginUserDetailsServiceImpl" class="com.emusicstore.serviceImpl.LoginUserDetailsServiceImpl"/>
<bean id="CustomerDao" class="com.emusicstore.daoImpl.CustomerDaoImp"/>
I get the following error 'org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.emusicstore.dao.CustomerDao] is defined: expected single matching bean but found 2: customerDaoImp,CustomerDao'
The problem is a CustomerDao instance can't be found by Spring. Either it's failed to instantiate somewhere higher up in your logs, or likely it hasn't been defined in a way that it can be instantiated and made available for injection by Spring Framework.
If you're using XML based dependency injection then defined CustomerDao instance with id customerDao in your XML similar to how LoginUserDetailsServiceImpl is defined.
Or if you're using annotation based dependency injection then add the appropriate stereotype annotation (#Component, #Repository etc) to the CustomerDao so Spring IoC knows to instantiate it and make is available for dependency injection.

Annotation not working in spring

i am a beginner in spring ,i have a dao class in spring .but annotation # auto wired or # service is not working ,i have solved the issue by creating a bean in application context,what is the reason for annotation not working in spring .provided with "context:component-scan base-package=" also but annotations are not working
StudentDao
public interface StudentDao {
public int addStudent(StudentEntity s);
}
-----------------------------------
#Service("studentDaoImpl")
public class StudentDaoImpl implements StudentDao{
#PersistenceContext
private EntityManager em;
#Override
#Transactional
public int addStudent(StudentEntity student) {
// TODO Auto-generated method stub
em.persist(student);
return student.getId();
}
}
------------------------------------------------
FascadeDaoImpl
public class FascadeControllerImpl implements FascadeController {
// #Autowired
private StudentDao studentDao;
private UserContext uc;
public void studentDao() {
studentDao=(StudentDao) uc.getContext().getBean("studentDao");
}
}
public int addStudent(StudentEntity student) {
studentDao();
return studentDao.addStudent(student);
}
ApplicationContext
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<context:component-scan base-package="sms.spring.dao" />
<context:component-scan base-package="sms.spring.fascade" />
<context:component-scan base-package="sms.spring.entity" />
<context:annotation-config />
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean class="sms.spring.entity.StudentEntity" id="studentbean"/>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.microsoft.sqlserver.jdbc.SQLServerDriver</value>
</property>
<property name="url">
<value>jdbc:sqlserver://localhost;databaseName=dbstsms</value>
</property>
<property name="username">
<value>sa</value>
</property>
<property name="password">
<value>sa123</value>
</property>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml" />
<property name="persistenceUnitName" value="PERSUnit" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="fascadeController" class="sms.spring.fascade.FascadeControllerImpl"></bean>
<bean id="studentDao" class="sms.spring.dao.StudentDaoImpl"></bean>
<bean id="loginDao" class="sms.spring.dao.LoginDaoImpl"></bean>
<bean id="facultyDao" class="sms.spring.dao.FacultyDaoImpl"></bean>
<bean id="markDao" class="sms.spring.dao.MarkDaoImpl"></bean>
<bean id="notificationDao" class="sms.spring.dao.NotificationDaoImpl"></bean>
<tx:annotation-driven />
Please post the error that you are getting,Also from the code you have posted I can see that even though you have annotated the StudentDaoImpl class with #service annotation you are again defining the same in the xml configuration,Kindly use either annotation based config or xml based configuration.
Please check if your file has
<context:annotation-config/> is mentioned in the xml config(Not needed if component scan is enabled)
Check if component scan is enabled for the package
Please refer to this answer for the correct schema location
Question is not clear, but it looks like your controller should also be annotated with #Controller. All classes belonging to a Spring project that have autowired dependencies, need to be created by Spring. In short, you should never make a new of a Spring class and create them using the ApplicationContext#getBean() or when it gets injected by another class.
Moreover, bear in mind with the constructors as at the point of creation of the bean the autowired dependencies are null (not initialized) and you need to create an init() method annotated with #PostConstruct.
Two main causes are:
You must tell spring, where to scan your components (make sure the packages are right)
You don't have an implementation of an actual bean (make sure StudentDao have #Service too)

component-scan not finding #Repository

My classes look like this:
AbstractDAO
package dao.impl;
public abstract class AbstractDAO <E> implements DAO<E> {
#PersistenceContext
private EntityManager em;
public void add(E entity) {
em.persist(entity);
}
}
DAOImpl
package dao.impl;
#Transactional
#Repository
public class ItemDAOImpl extends AbstractDAO<Item> {
}
application-context-test.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<context:component-scan base-package="dao.impl" />
<bean id="entityManagerFactoryBean"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="domain" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.archive.autodetection">class</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/inventory" />
<property name="username" value="root" />
<property name="password" value="1234" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactoryBean" />
</bean>
<tx:annotation-driven />
TEST class
package service.impl;
#ContextConfiguration(locations = "classpath:application-context-test.xml")
#RunWith(SpringJUnit4ClassRunner.class)
public class ItemTest {
#Autowired
private ItemDAOImpl itemDAO;
#Test
public void testCreateItem() throws Exception {
Item item = new Item("cellphone", "galaxy", ItemType.TECHNOLOGY, 10000);
itemDAO.add(item);
assertEquals(5, itemDAO.list(Item.class).size());
}
}
Should not this code be able to autowire my itemDAO?
When I run my test it throws an exception saying
org.springframework.beans.factory.BeanCreationException: Could not autowire
field: private dao.impl.ItemDAOImpl service.impl.ItemTest.itemDAO; nested
exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [dao.impl.ItemDAOImpl] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this
dependency. Dependency annotations:
Could you please tell what am I missing? The only thing I can think about is that since my test is in src/test/java, my application-context-test.xml is in src/test/resources and my dao is in src/main/java. Maybe the component-scan scanning in the wrong place?
Because ItemDAOImpl is annotated with #Transactional, spring will create a proxy for this bean and inject the proxy, not the bean itself when autowiring.
Spring can create proxies by subclassing (using Cglib) or by implementing the beans interfaces with Jdk proxies.
Which type of proxy spring uses, depends on your configuration.
I had similar problems as you described and the cause was, that spring used Jdk proxies and I wasnt aware of it.
In your case the spring bean for ItemDaoImpl would be a proxy implementing DAO.
This cannot be injected into
#Autowired
private ItemDAOImpl itemDAO;
because it cannot be cast to ItemDaoImpl.
That would explain the exception you are facing.
To fix that, change the field to
#Autowired
private DAO<Item> itemDAO;
The above only works, if you are using spring 4.
With earlier versions of spring you have to create an interface
public interface ItemDAO extends DAO<Item>
and let ItemDaoImpl implement it.
Finally change your field where you want it to be injected to
#Autowired
private ItemDAO itemDAO;

Two session Factories found when one was expected

I have referred to the question asked at Hibernate using multiple databases. My problem is similar but I am facing a different problem.I created two xml file each has a separate datasource and session factory.
In my web.xml I have
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>*The xml files* </param-value>
Once I run the project,the various loadings and the bindings are done from both the xml files.The various annotations and databases/tables are properly identified.But just after this is done before the control even goes outside.I get the following error.
main ERROR [org.springframework.web.context.ContextLoader] - Context initialization failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'daoEager' defined in URL [jar:file:/C:/Users/.../.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/infobutton-service/WEB-INF/lib/core-data-1.0.0-SNAPSHOT.jar!/.../DaoHibernateEagerImpl.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [org.hibernate.SessionFactory]: : No unique bean of type [org.hibernate.SessionFactory] is defined: expected single matching bean but found 2: [sessionFactory, profilesessionFactory]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.hibernate.SessionFactory] is defined: expected single matching bean but found 2: [sessionFactory, profilesessionFactory]
The class DaoHibernateEagerImpl is
#Implementation
#Repository("daoEager")
public class DaoHibernateEagerImpl extends DaoHibernateImpl
{
// ========================= CONSTANTS =================================
/**
* A logger that helps identify this class' printouts.
*/
private static final Logger log = getLogger(DaoHibernateEagerImpl.class);
// ========================= CONSTRUCTORS ==============================
/**
* Required for a Spring DAO bean.
*
* #param sessionFactory
* Hibernate session factory
*/
#Autowired
public DaoHibernateEagerImpl(final SessionFactory sessionFactory)
{
super(sessionFactory);
}
// ========================= DEPENDENCIES ==============================
// ========================= IMPLEMENTATION: Dao =======================
// ========================= IMPLEMENTATION: SearchEngine ==============
}
One of the xml files is
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<context:annotation-config />
<!--
Data source: reads a properties file and injects them into a DBCP DS
Second datasource for Resource Profiles
-->
<bean id="profiledataSource"
class=".....ConfigurableBasicDataSource">
<constructor-arg index="0">
<bean class="org.apache.commons.dbcp.BasicDataSource" />
</constructor-arg>
<property name="properties">
<bean
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>WEB-INF/datasource-local.properties
</value>
</list>
</property>
</bean>
</property>
<!-- FUR-946: idle connections break. Adding connection testing. -->
<property name="testOnBorrow" value="true" />
<property name="testWhileIdle" value="true" />
</bean>
<!-- Session factory -->
<!-- Session Factory for the second datasource-->
<bean id="profilesessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="profiledataSource" />
<!--
Hibernate configuration properties (read from a properties file)
-->
<property name="hibernateProperties">
<bean
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>WEB-INF/hibernate.properties
</value>
<value>WEB-INF/datasource-local.properties
</value>
</list>
</property>
</bean>
</property>
<!-- Using improved naming strategy -->
<property name="namingStrategy">
<bean class="org.hibernate.cfg.DefaultNamingStrategy" />
</property>
<!-- Mapping annotated classes using search patterns -->
<property name="annotatedClasses">
<list>
<value><![CDATA[....profiledb.domain.Profiles]]></value>
</list>
</property>
</bean>
<!-- Hibernate data access template -->
<bean id="profilehibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="profilesessionFactory" />
</bean>
<tx:annotation-driven />
<!-- a PlatformTransactionManager is still required -->
<bean id="profiletransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="profilesessionFactory" />
</bean>
<bean id="profilesdbDao" class="....profiledb.service.ProfilesDaoImpl" >
<property name="sessionFactory" ref="profilesessionFactory"></property>
<context:component-scan base-package="....core.data" />
The other xml file is similar but has a different datasource and the session factory is
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
.....
The error message is pretty clear:
expected single matching bean but found 2: [sessionFactory, profilesessionFactory]
Which is understandable:
<bean id="profilesessionFactory"
<!-- ... -->
<bean id="sessionFactory"
The fix should be simple:
#Autowired
public DaoHibernateEagerImpl(
#Qualifier("profilesessionFactory") final SessionFactory sessionFactory)
If you cannot modify DaoHibernateEagerImpl class, you can always fall-back to XML-based configuration. First disable CLASSPATH scanning of DaoHibernateEagerImpl so that #Autowired is not picked up. Then simply write:
<bean class="DaoHibernateEagerImpl">
<constructor-arg ref="profilesessionFactory"/>
<!-- ... -->
</bean>
Finally you can take advantage of #Primary annotation / primary="true" directive:
<bean id="sessionFactory" primary="true">
<!-- ... -->
This will prefer sessionFactory when autowiring and there are two possibilities instead of throwing an exception.
Its because of...if you dont mention #Primary(annotation) / primary="true"(in xml config), Hiibernate does not know which sessionfactory to pick up.In that case it will give you the error mentioned. Just try with #Primary annotation it will work...

Debugging "Injection of autowired dependencies failed" Error in Spring+Hibernate

I have just started with Spring Framework and trying to develop and run a simple a app using Spring + Hibernate + Maven for dependency management.
I have a ContactController in which a property of type ContactService is Autowired. But when i packaged it into war and deployed on tomcat it throws a org.springframework.beans.factory.BeanCreationException with following messages :
org.springframework.beans.factory.BeanCreationException: Error creating bean with name
'sessionFactory' defined in ServletContext resource [/WEB-INF/spring-servlet.xml]:
Invocation of init method failed; nested exception is org.hibernate.MappingException:
An AnnotationConfiguration instance is required to use <mapping
class="org.kodeplay.contact.form.Contact"/>
So I commented out that property from the ContactController Class along with all its references and re deployed it. But still it shows the same error.
This is the only controller in the entire application and an object implementing the ContactService interface is not being used any where else.
Whats going on here ? Am I missing something ?
Edit : Adding the code for spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<context:annotation-config/>
<context:component-scan base-package="org.kodeplay.contact" />
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- Internationalization -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages" />
<property name="defaultEncoding" value="UTF-8" />
</bean>
<!-- To load database connection details from jdbc.properties file -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="/WEB-INF/jdbc.properties" />
<!-- To establish a connection to the database -->
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.databaseurl}" p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<!-- Hibernate configuration -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="annotatedClasses">
<list>
<value>org.kodeplay.contact.form.Contact</value>
</list>
</property>
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:hibernate.cfg.xml</value>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${jdbc.dialect}</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<tx:annotation-driven/>
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
</beans>
code for hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping class="org.kodeplay.contact.form.Contact" />
</session-factory>
</hibernate-configuration>
Thanks
I suspect this be a clash between AnnotationSessionFactoryBean and hibernate.cfg.xml. If you're using the former, you shouldn't need the latter. If you use both, you're going to have to duplicate some settings, and the cfg file might be eclipsing the Spring config.
Whatever you have in hibernate.cfg.xml you should be able to move into the bean definition for the AnnotationSessionFactoryBean, and that should resolve your error.
I guess you try to configure Hibernate with org.springframework.orm.hibernate3.LocalSessionFactoryBean. However, you use annotations in Hibernate mapping, therefore you need to use org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean instead.

Categories

Resources