Jack
Jack

Reputation: 491

Java spring + hibernate interface (DAO) <bean>

This is a very simple spring + hibernate example. What am I doing wrong here?

DTO:

package com.xx.dto;

import java.util.Date;
import javax.persistence.*;

@Entity
@Table(name = "users")
public class UserData {

    @Id
    @GeneratedValue
    @Column(name = "id")
    private Integer id;

    @Column(name = "user_firstname")
    private String firstname;

    @Column(name = "user_lastname")
    private String lastname;

    @Column(name = "user_sex")
    private String sex;

    @Column(name = "user_birthdate")
    private Date birthDate;

    @Column(name = "user_email")
    private String email;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(Date birthDate) {
        this.birthDate = birthDate;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

DAO interface:

package com.xx.dao;

import java.util.List;
import com.provisori.dto.UserData;

public interface UserDataDao {

    void saveUser(UserData user);

    void deleteUser(String key);

    void updateUser(UserData user);

    List<UserData> listUser();
}

DAO implementation:

package com.xx.imp;

import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.provisori.dao.UserDataDao;
import com.provisori.dto.UserData;

public class UserDataImp implements UserDataDao{

    @Autowired
    SessionFactory sessionFactory;

    @Transactional
    @Override
    public void saveUser(UserData user) {
        sessionFactory.getCurrentSession().save(user);
    }

    @Transactional
    @SuppressWarnings("unchecked")
    @Override
    public List<UserData> listUser() {
        return sessionFactory.getCurrentSession()
                .createCriteria(UserData.class).list();
    }

    @Transactional
    @Override
    public void updateUser(UserData user) {
        sessionFactory.getCurrentSession().update(user);

    }

    @Transactional
    public UserData getUser(String key) {
        Session session = sessionFactory.getCurrentSession();
        Criteria criteria = session.createCriteria(UserData.class);
        criteria.add(Restrictions.eq("key", key));
        return (UserData) criteria.uniqueResult();
    }

    @Transactional
    @Override
    public void deleteUser(String key) {
        UserData user = getUser(key);
        sessionFactory.getCurrentSession().delete(user);
    }
}

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

    <!-- Needed for Autowiring -->
    <context:annotation-config />

    <!-- MySQL DataSource -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/xx" />
        <property name="user" value="root" />
        <property name="password" value="" />
    </bean>

    <!-- Hibernate SessionFactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.provisori.dto.UserData</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <value>
                hibernate.hbm2ddl.auto=update
                hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
            </value>
        </property>
    </bean>

    <!-- Transaction Management -->
    <tx:annotation-driven transaction-manager="txManager" />
    <bean id="txManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- Java Bean -->
    <bean id="userDataDao" class="com.provisori.imp.UserDataImp" />

</beans>

Main.class

package com.provisori.dto;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.provisori.dao.UserDataDao;
import com.provisori.imp.UserDataImp;

public class TestMain {

   public static void main(String[] args) {

      // Construct the spring application context
      AbstractApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

      // Register hook to shutdown Spring gracefully
      // See http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-factory-shutdown
      context.registerShutdownHook();

      // Get the business bean from context
      UserDataDao dao = (UserDataImp) context.getBean("userDataDao");

      // Create simple property objects
      UserData user = new UserData();
      user.setFirstname("firstnameTest");
      user.setLastname("lastnameTest");
      dao.saveUser(user);
   }
}

result

Exception in thread "main" java.lang.ClassCastException: $Proxy13 cannot be cast to com.provisori.imp.UserDataImp at com.provisori.dto.TestMain.main(TestMain.java:21)

Upvotes: 2

Views: 9018

Answers (2)

Maciej Ziarko
Maciej Ziarko

Reputation: 12114

You can't instantiate interface.

Your code:

<!-- Business Bean -->
<bean id="userDataDao" class="com.provisori.dao.UserDataDao">  
    <property name="userDataImp" ref="userDataImp" />  
</bean>
<bean id="userDataImp" class="com.provisori.imp.UserDataImp" />

You need to remove the first bean called userDataDao. I recommend reading Spring Docs as you probably don't know/understand Spring IoC container basics.

Documentation is your friend: READ

EDITED After you changed source code, stacktrace in your question:

Your code:

UserDataDao dao = (UserDataImp) context.getBean("userDataDao");

try changing it to:

UserDataDao dao = (UserDataDao) context.getBean("userDataDao"); 

Your current error is caused by Spring-generated proxy class that is not a subclass of UserDataImp but it implements the same interface. So it cannot be cast to your concrete implementation. Instead you need to user interface.

Upvotes: 3

Reimeus
Reimeus

Reputation: 159854

The error is a good indicator — interfaces can't be instantiated. Use the bean implementation:

<bean id="userDataDao" class="com.provisori.imp.UserDataImp"> 

Upvotes: 5

Related Questions