Results 1 to 10 of 10

Thread: help on @Transactional in TX

  1. #1
    Join Date
    Jul 2009
    Posts
    8

    Unhappy help on @Transactional in TX

    im getting this error
    Code:
    Exception in thread "main" java.lang.ClassCastException: $Proxy17 cannot be cast to com.*********.database.service.StoryService
    	at com.*********.test.Main.main(Main.java:28)


    here is my context xml
    Code:
    <bean id="sessionFactory"
    		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
    		p:dataSource-ref="dataSource" p:hibernateProperties-ref="hibernateProperties"
    		p:annotatedClasses-ref="hibernatePojoModelClasses" />
    
    	<bean id="transactionManager"
    		class="org.springframework.orm.hibernate3.HibernateTransactionManager"
    		p:sessionFactory-ref="sessionFactory" />
    
    	<tx:annotation-driven transaction-manager="transactionManager" />
    
    	<bean id="storyDao" class="com.*********.database.dao.StoryDao">
    		<constructor-arg ref="sessionFactory" />
    	</bean>
    
    
    	<bean id="storyService" class="com.*********.database.service.StoryService"
    		p:storyDao-ref="storyDao" />
    and here is my service class
    Code:
    	@Transactional(readOnly = true)
    	public Set<Story> findUserStory(User user) {
    
    		return null;
    	}
    and last, this is my test class
    Code:
    StoryService storyS = (StoryService) context.getBean("storyService");

    looks like everything is in place, like the example in the book.

    help plz!

  2. #2
    Join Date
    Jan 2008
    Location
    San Diego
    Posts
    780

    Default

    StoryService needs to be an interface not a class. Your StoryService bean should implement the StoryService interface.

  3. #3
    Join Date
    Jul 2009
    Posts
    8

    Default

    thank you for the reply! i will try it out.


    but why tho? w/o having the annotation, it was totally fine

  4. #4
    Join Date
    Jan 2008
    Location
    San Diego
    Posts
    780

    Default

    Because the annotation adds a transactional wrapper (proxy) around your class. The wrapper can implement an interface but it cannot extend a class. When you try and pass it as an argument where a class type is expected you will get a class cast exception. When you pass it as an argument where an interface is expected, it will work.

    If you aren't defining interfaces for you services, you should be. How are you testing the collaborators that use them?

  5. #5
    Join Date
    Jul 2009
    Posts
    8

    Default

    gotta ya! thank you so much again for explaining that

  6. #6
    Join Date
    Jul 2009
    Posts
    8

    Default

    chudak,

    i tried w/ the interface and still getting this
    Code:
    Exception in thread "main" java.lang.ClassCastException: $Proxy24 cannot be cast to


    really confused

  7. #7
    Join Date
    Jan 2008
    Location
    San Diego
    Posts
    780

    Default

    Post your code and configuration...

  8. #8
    Join Date
    Jul 2009
    Posts
    8

    Default

    context.xml
    Code:
    <?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:p="http://www.springframework.org/schema/p"
    	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
    	xsi:schemaLocation="
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd">
    
    
    	
    
    
    	<!-- LISTS -->
    	<util:list id="hibernatePojoModelClasses">
    		<value>com.test.database.model.Vote</value>
    		<value>com.test.database.model.Picture</value>
    		<value>com.test.database.model.User</value>
    	</util:list>
    
    	<util:properties id="hibernateProperties">
    		<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
    		<prop key="hibernate.hbm2ddl.auto">update</prop>
    		<prop key="show_sql">true</prop>
    		<prop key="hibernate.c3p0.minPoolSize">5</prop>
    		<prop key="hibernate.c3p0.maxPoolSize">20</prop>
    		<prop key="hibernate.c3p0.timeout">600</prop>
    		<prop key="hibernate.c3p0.max_statement">50</prop>
    		<prop key="hibernate.format_sql">true</prop>
    		<prop key="hibernate.generate_statistics">true</prop>
    	</util:properties>
    
    	<!-- DATA SOURCE -->
    	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    		destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver"
    
    		p:url="jdbc:mysql://localhost:3306/test" p:username="test"
    		p:password="****" p:removeAbandoned="true" p:removeAbandonedTimeout="60"
    		p:maxActive="100" p:maxIdle="30" p:maxWait="-1" />
    
    
    	<bean id="sessionFactory"
    		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"
    		p:dataSource-ref="dataSource" p:hibernateProperties-ref="hibernateProperties"
    		p:annotatedClasses-ref="hibernatePojoModelClasses" />
    
    	<bean id="transactionManager"
    		class="org.springframework.orm.hibernate3.HibernateTransactionManager"
    		p:sessionFactory-ref="sessionFactory" />
    
    	<tx:annotation-driven transaction-manager="transactionManager" />
    
    
    	<!-- DAOs -->
    	<bean id="userDao" class="com.test.database.dao.UserDao">
    		<constructor-arg ref="sessionFactory" />
    	</bean>
    	<bean id="pictureDao" class="com.test.database.dao.PictureDao">
    		<constructor-arg ref="sessionFactory" />
    	</bean>
    	<bean id="voteDao" class="com.test.database.dao.VoteDao">
    		<constructor-arg ref="sessionFactory" />
    	</bean>
    
    	<!-- SERVICEs -->
    	<!--
    		<bean id="pictureService"
    		class="com.test.database.service.PictureService"
    		p:pictureDao-ref="pictureDao" />
    	-->
    
    	<bean id="userService" class="com.test.database.service.UserService"
    		p:userDao-ref="userDao" />
    	<bean id="voteService" class="com.test.database.service.VoteService"
    		p:voteDao-ref="voteDao" />
    
    
    </beans>

    interface
    Code:
    public interface IUserService {
    
    	public User register(User user);
    
    	public User findUserById(String id);
    
    	@Transactional
    	public User findUserByEmail(String email);
    
    	public User login(String email, String password);
    
    }

    implement
    Code:
    public class UserService implements IUserService, UserDaoIoC {
    
    	private UserDao dao;
    
    	/*
    	 * (non-Javadoc)
    	 * 
    	 * @see
    	 * com.test.database.service.IUserService#findUserByEmail(java.lang.
    	 * String)
    	 */
    	public User findUserByEmail(String email) {
    
    		List<?> users = this.dao.findByNamedQuery("user.findByEmail", "email",
    				email);
    
    		if (users.size() > 0) {
    			return (User) users.get(0);
    		} else {
    			return null;
    		}
    	}
    
    	/*
    	 * (non-Javadoc)
    	 * 
    	 * @see
    	 * com.test.database.service.IUserService#findUserById(java.lang.String)
    	 */
    	public User findUserById(String id) {
    		// TODO Auto-generated method stub
    		return null;
    	}
    
    	/*
    	 * (non-Javadoc)
    	 * 
    	 * @see com.test.database.service.IUserService#login(java.lang.String,
    	 * java.lang.String)
    	 */
    	public User login(String email, String password) {
    		// TODO Auto-generated method stub
    		return null;
    	}
    
    	/*
    	 * (non-Javadoc)
    	 * 
    	 * @see
    	 * com.test.database.service.IUserService#register(com.test.database
    	 * .model.User)
    	 */
    	public User register(User user) {
    
    		this.dao.save(user);
    		return user;
    	}
    
    	/*
    	 * (non-Javadoc)
    	 * 
    	 * @see
    	 * com.test.ioc.database.dao.UserDaoIoC#setUserDao(com.test.database
    	 * .dao.UserDao)
    	 */
    	public void setUserDao(UserDao dao) {
    		this.dao = dao;
    
    	}
    
    }

    testing
    Code:
    public class Main {
    
    	/**
    	 * 
    	 */
    	public Main() {
    		// TODO Auto-generated constructor stub
    	}
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    
    		ApplicationContext context = new ClassPathXmlApplicationContext(
    				"applicationContext.xml");
    
    		UserService us = (UserService) context.getBean("userService");
    
    		
    		
    		System.out.println(us.findUserByEmail("test@test.com").getMemberSince());
    		
    	}
    
    }

  9. #9
    Join Date
    Jan 2008
    Location
    San Diego
    Posts
    780

    Default

    You are still trying to cast the bean to it's CLASS...you need to cast it to it's INTERFACE:

    Code:
    IUserService us = (IUserService) context.getBean("userService");
    Program to INTERFACES not IMPLEMENTATIONS...

  10. #10
    Join Date
    Jul 2009
    Posts
    8

    Default

    hah you are right. forgot to change in the testing class

    thank you so much man!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •