1

I am trying to implement a signup page using Spring MVC integrated with hibernate using XML.

Application Context.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:p="http://www.springframework.org/schema/p"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
 xmlns:tx="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> 

   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">  
        <property name="driverClassName"  value="oracle.jdbc.driver.OracleDriver"></property>  
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></property>  
        <property name="username" value="hr"></property>  
        <property name="password" value="umashetti123"></property>  
    </bean>  

    <bean id="mysessionFactory"  class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">  
        <property name="dataSource" ref="dataSource"></property>  

        <property name="mappingResources">  
        <list>  
        <value>Login_Detailshbm.xml</value>  
        </list>  
        </property>  

        <property name="hibernateProperties">  
            <props>  
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>  
                <prop key="hibernate.hbm2ddl.auto">update</prop> 
                <prop key="hibernate.show_sql">true</prop>  
                <prop key="checkWriteOperation" >false</prop> 

            </props>  
        </property>  
    </bean>  

    <bean id="template" class="org.springframework.orm.hibernate5.HibernateTemplate">  
    <property name="sessionFactory" ref="mysessionFactory"></property> 
    <property name="checkWriteOperations" value="false"></property>
    </bean>

 <tx:annotation-driven />
<bean id="transactionManager"
    class="org.springframework.orm.hibernate5.HibernateTransactionManager">
    <property name="sessionFactory" ref="mysessionFactory" />
</bean>


    <bean id="d" class="com.uday.Login_DetailsDao">  
    <property name="template" ref="template"></property>  
    </bean>  

    </beans>  

Controller Class

package com.uday;

import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;





@Controller
public class ControllerSignUp_Login {


    public ControllerSignUp_Login() {
        // TODO Auto-generated constructor stub
    }

    @RequestMapping("/hello")   
    public String diaplay(@RequestParam("name") String name, @RequestParam("pass") String pass,Model m) {
        Login_DetailsDao dao = (Login_DetailsDao) getBean(); 

        if(dao.isLogoinSuccessfull(name , pass)) {
            m.addAttribute("message", "Hello"+name);
            return "Success";
        }
        else {
            m.addAttribute("message", "You have Entered Wrong pin");
            return "Failure";
        }
    }

    @RequestMapping("/SignUp")
    public String redirect() {
        System.out.println("ControllerSignUp_Login.display()");
        return "signup";
    }

    @RequestMapping("/login")
    public String display() {
        System.out.println("ControllerSignUp_Login.display()");
        return "login";
    }

    @RequestMapping("/updateDetails")
    @Transactional
    public String display(HttpServletRequest req , Model M) {
        String firstName=req.getParameter("firstName");  
        String lastName=req.getParameter("lastName"); 
        String mobileNo=req.getParameter("mobileNo");  
        String address=req.getParameter("address");  
        String city=req.getParameter("city");  
        String password=req.getParameter("password");             
        Login_DetailsDao dao = (Login_DetailsDao) getBean();        
        if(checkLength(firstName)  && checkLength(lastName) && checkLength(mobileNo) && checkLength(address) && checkLength(city) &&  checkLength(password)) {
            Login_Details ld = new Login_Details();
            ld.setFirstName(firstName);
            ld.setLastName(lastName);
            ld.setCity(city);
            ld.setAddress(address);
            ld.setMobileNo(mobileNo);
            ld.setPassword(password);

            dao.saveEmployee(ld);
            M.addAttribute("message", "SignUp Successfull !! Thank You");
            M.addAttribute("displayLogin", true);
            return "Success";
        }
        else {
            M.addAttribute("message","SignUp Failed !! All details are mandatory.");
            return "signup";

        }
    }

    public boolean checkLength(String s) {
        if(s != null && s.length() > 0) {
            return true;
        }
        return false;

    }

    public Object getBean() {
        ApplicationContext  appcontext = new ClassPathXmlApplicationContext("Applicationcontext.xml");            
        Login_DetailsDao lDDao =(Login_DetailsDao)appcontext.getBean("d");  
        return lDDao;
    }


}

DAO class

package com.uday;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.springframework.orm.hibernate5.HibernateTemplate;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.transaction.annotation.Transactional;


public class Login_DetailsDao {


    HibernateTemplate template; 

    HibernateTransactionManager hbt;



    public HibernateTransactionManager getHbt() {
        return hbt;
    }

    public void setHbt(HibernateTransactionManager hbt) {
        this.hbt = hbt;
    }

    public Login_DetailsDao() {
        // TODO Auto-generated constructor stub
    }

    @Transactional
    public void saveEmployee(Login_Details e){  
        System.out.println("Login_DetailsDao.saveEmployee()"+e.getMobileNo());
        SessionFactory sf = hbt.getSessionFactory();
        Session session   =sf.getCurrentSession();
        Transaction t     =session.beginTransaction();   
        session.persist(e);         
        t.commit();  
        session.close();    
    }

    public void setTemplate(HibernateTemplate template) {  
        this.template = template;  
    } 

    public List<Login_Details> getEmployees(){  
        List<Login_Details> list=new ArrayList<Login_Details>();  
        list=template.loadAll(Login_Details.class);  
        return list;  
    } 

}

I am able to get the login_details data but unable to insert the record.

getting below exception

org.xml.sax.SAXParseException; lineNumber: 51; columnNumber: 29; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'tx:annotation-driven'.

Could any one please suggest to solve this?

Uday Kumar
  • 123
  • 10
  • Saving without proper transaction management won't work. – M. Deinum Apr 23 '19 at 12:11
  • @M.Deinum Could you tell me how to do that? – Uday Kumar Apr 23 '19 at 12:19
  • Configure a `HibernateTransactionManager` in your XML. Add `` and add `@Transactional` to your service methods. Ditch `HibernateTemplate` and use a plain `SessionFactory` with `SessionFactory.getCurrentSession()` to o btain the current bound session. `HibernateTemplate` isn't recommended anymore since about hibernate 3.0.1. – M. Deinum Apr 23 '19 at 12:21
  • @M.Deinum org.xml.sax.SAXParseException; lineNumber: 51; columnNumber: 29; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'tx:annotation-driven'. getting this exception on adding this – Uday Kumar Apr 24 '19 at 06:00
  • Ofcourse you will get it without adding the tx namespace. – M. Deinum Apr 24 '19 at 06:00
  • @M.Deinum this is added FYI xmlns:tx="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd" – Uday Kumar Apr 24 '19 at 06:01
  • Please don't add additional code/xml/... as comments, they become unreadable. Instead edit your question. – M. Deinum Apr 24 '19 at 06:02
  • @M.Deinum Edited Question. – Uday Kumar Apr 24 '19 at 06:08
  • 1
    That is wrong. You should have that in your `schemaLocation` and only the definition in the `xml:tx` part. – M. Deinum Apr 24 '19 at 06:36
  • @M.Deinum Yes you are ryt !! but getting some other exception org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread – Uday Kumar Apr 24 '19 at 07:02
  • Your configuration posted here doesn't make sense either. Your bean is namd `mysessionfactory` but you are injecting `sessionFactory` into the `HibernateTransactionManager`. So what you posted here cannot work, unless you have multiple `SessionFactory` instances, which should be (generally) a wrong thing to do. – M. Deinum Apr 24 '19 at 11:01
  • Also remove the `HibernateTemplate` and `HibernateTransactionManager` from your `LoginDao`. Just inject the `SessionFactory` don't try to get it trhough other beans. – M. Deinum Apr 24 '19 at 11:03
  • Finally your controller is wrong. Never create a beanfactory or application context to obtain a bean. This is basically bootstrapping your whole application again. Unless ofcourse you want to run into memory issues, weird transaction issues and performance issues. – M. Deinum Apr 24 '19 at 11:06

3 Answers3

0

Your code is flawed on multiple levels.

  1. Never create a BeanFactory or ApplicationContext just because you need an instance of a bean. Instead use dependency injecting for that bean.
  2. The fact that you use a BeanFactory over an ApplicationContext is one of the reasons your code doesn't work. See this for why you shouldn't use a BeanFactory.
  3. You aren't using transactions and without transactions nothing will be persisted in the database.

Now first in your controller you need to dependency inject the Login_DetailsDao instead of creating a BeanFactory and obtain an instance.

@Controller
public class ControllerSignUp_Login {

    private final Login_DetailsDao dao;

    @Autowired // If using Spring 4.3 or later this isn't needed
    public ControllerSignUp_Login(Login_DetailsDao dao) {
        this.dao=dao;
    }    
}

Now in your method use this instance, instead of doing the lookup.

Your Login_DetailsDao should operate on the SessionFactory and nothing else.

public class Login_DetailsDao {


    private final SessionFactory sf; 

    public Login_DetailsDao(SessionFactory sf) {\
        this.sf=sf;
    }

    @Transactional
    public void saveEmployee(Login_Details e){  
        sf.getCurrentSession().save(e);
    }

    @Transactional(readOnly=true)
    public List<Login_Details> getEmployees(){  
        return sf.getCurrentSession()
                 .createQuery("SELECT ld FROM Login_Details", Login_Details.class)
                 .getResult();
    } 
}

That is all you need. Now finally in your XML tie all this together.

<?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"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd"
 xmlns:tx="http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> 

    <tx:annotation-driven />

   <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">  
        <property name="driverClassName"  value="oracle.jdbc.driver.OracleDriver"></property>  
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></property>  
        <property name="username" value="hr"></property>  
        <property name="password" value="umashetti123"></property>  
    </bean>  

    <bean id="sessionFactory"  class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">  
        <property name="dataSource" ref="dataSource"></property>  

        <property name="mappingResources">  
        <list>  
        <value>Login_Detailshbm.xml</value>  
        </list>  
        </property>  

        <property name="hibernateProperties">  
            <props>  
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>  
                <prop key="hibernate.hbm2ddl.auto">update</prop> 
                <prop key="hibernate.show_sql">true</prop>  
                <prop key="checkWriteOperation" >false</prop> 

            </props>  
        </property>  
    </bean>  

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>


    <bean id="d" class="com.uday.Login_DetailsDao">
        <constructor-arg ref="sessionFactory" />  
    </bean>  

</beans>  
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
  • @Deinum Error creating bean with name 'controllerSignUp_Login' defined in file [C:\Users\umashetti\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\SpringUpalApp\WEB-INF\classes\com\uday\ControllerSignUp_Login.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.uday.Login_DetailsDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {} – Uday Kumar Apr 24 '19 at 12:13
  • Add this xml file to the list of files the `DispatcherServlet` loads. Or use an `` in your main xml file. – M. Deinum Apr 24 '19 at 12:59
  • @ M.Deinum Thank you so much !! for helping me through out of making this application . – Uday Kumar Apr 25 '19 at 06:39
0

One simple change made this application worked.

1 > Deleted applicationcontext.xml and added the contents in disapatcher-servlet.xml

disaptcher-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-3.0.xsd">  

        <context:annotation-config/>

 <tx:annotation-driven />

    <!-- Provide support for component scanning -->  
    <context:component-scan base-package="com.uday" />  

    <!--Provide support for conversion, formatting and validation -->  
    <mvc:annotation-driven/>  
<!-- Define Spring MVC view resolver -->  
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="prefix" value="/WEB-INF/page/"></property>  
        <property name="suffix" value=".jsp"></property>          
     </bean> 

       <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">  
        <property name="driverClassName"  value="oracle.jdbc.driver.OracleDriver"></property>  
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></property>  
        <property name="username" value="hr"></property>  
        <property name="password" value="umashetti123"></property>  
    </bean>  

    <bean id="mysessionFactory"  class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">  
        <property name="dataSource" ref="dataSource"></property>  

        <property name="mappingResources">  
        <list>  
        <value>Login_Detailshbm.xml</value>  
        </list>  
        </property>  

        <property name="hibernateProperties">  
            <props>  
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>  
                <prop key="hibernate.hbm2ddl.auto">update</prop> 
                <prop key="hibernate.show_sql">true</prop>  
                <prop key="checkWriteOperation" >false</prop> 

            </props>  
        </property>  
    </bean>  

    <bean id="transactionManager"
        class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="mysessionFactory" />
    </bean>

    <bean id="d" class="com.uday.Login_DetailsDao">  
    <constructor-arg ref="mysessionFactory" /> 
    </bean>   


</beans>  

DAO Class:

package com.uday;

import java.util.Iterator;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.springframework.transaction.annotation.Transactional;


public class Login_DetailsDao {


    private final SessionFactory sessionFactory;


    public Login_DetailsDao(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional
    public void saveEmployee(Login_Details e){      
        sessionFactory.getCurrentSession().save(e);   
    }

    public boolean isLogoinSuccessfull(String uName , String password) {
        List<Login_Details> a= getEmployees();
        Iterator<Login_Details> i = a.iterator();
        while(i.hasNext()) {
            Login_Details ld = i.next();
            String mobileNo = ld.getMobileNo();
            String pas      = ld.getPassword();
            if(mobileNo != null && mobileNo.equals(uName)  && pas != null && pas.equals(password)) {
                return true;
            }
        }


        return false;

    }

    @Transactional
    public List<Login_Details> getEmployees(){  
        Criteria criteria =  sessionFactory.getCurrentSession().createCriteria(Login_Details.class);
        List<Login_Details> l = criteria.list();
        return l;
    } 

}

Controller Class:

package com.uday;

import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;


@Controller
public class ControllerSignUp_Login {

    @Autowired
    private final Login_DetailsDao dao;

    @Autowired
    public ControllerSignUp_Login(Login_DetailsDao login_DetailsDao) {
        this.dao = login_DetailsDao;
    }

    @RequestMapping("/hello")
    @Transactional
    public String diaplay(@RequestParam("name") String name, @RequestParam("pass") String pass,Model m) {
        if(dao.isLogoinSuccessfull(name , pass)) {
            m.addAttribute("message", "Hello"+name);
            return "Success";
        }
        else {
            m.addAttribute("message", "You have Entered Wrong pin");
            return "Failure";
        }
    }

    @RequestMapping("/SignUp")
    public String redirect() {
        System.out.println("ControllerSignUp_Login.display()");
        return "signup";
    }

    @RequestMapping("/login")
    public String display() {
        System.out.println("ControllerSignUp_Login.display()");
        return "login";
    }

    @RequestMapping("/updateDetails")
    @Transactional
    public String display(HttpServletRequest req , Model M) {
        String firstName=req.getParameter("firstName");  
        String lastName=req.getParameter("lastName"); 
        String mobileNo=req.getParameter("mobileNo");  
        String address=req.getParameter("address");  
        String city=req.getParameter("city");  
        String password=req.getParameter("password");       
        if(checkLength(firstName)  && checkLength(lastName) && checkLength(mobileNo) && checkLength(address) && checkLength(city) &&  checkLength(password)) {
            Login_Details ld = new Login_Details();
            ld.setFirstName(firstName);
            ld.setLastName(lastName);
            ld.setCity(city);
            ld.setAddress(address);
            ld.setMobileNo(mobileNo);
            ld.setPassword(password);
            dao.saveEmployee(ld);
            M.addAttribute("message", "SignUp Successfull !! Thank You");
            M.addAttribute("displayLogin", true);
            return "Success";
        }
        else {
            M.addAttribute("message","SignUp Failed !! All details are mandatory.");
            return "signup";

        }
    }

    public boolean checkLength(String s) {
        if(s != null && s.length() > 0) {
            return true;
        }
        return false;

    }

}

Project Structure looks like below

enter image description here

Uday Kumar
  • 123
  • 10
-1

Instead of getting current session and making the transaction opened new session that's it worked like charm!!!

I don't know why it is not working if I am getting current session!!

@Transactional
    public void saveEmployee(Login_Details e){  
        System.out.println("Login_DetailsDao.saveEmployee()"+e.getMobileNo());
        SessionFactory sf = hbt.getSessionFactory();
        //Changed here
        Session session   =sf.openSession(); //Session session   =sf.getCurrentSession();
        Transaction t     =session.beginTransaction();   
        session.persist(e);         
        t.commit();  
        session.close();    
    }
Uday Kumar
  • 123
  • 10
  • Don't... Please don't... The fact that you get the error indicates your configuration is wrong. This isn't a solution but a hacky workaround. Your method should actually only contain something like `sessionFactory.getCurrentSession().save(e)`, everything else should be handled for you. Remember you shouldn't be using `HibernateTemplate` anymore. – M. Deinum Apr 24 '19 at 11:00