org.hibernate.HibernateException:没有活动事务,合并无效

|| 首先,applicationContext.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:tx=\"http://www.springframework.org/schema/tx\"
       xsi:schemaLocation=\"
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd\">

    <bean class=\"info.ems.config.EMSConfigurer\"/>

    <bean id=\"passwordEncoder\" class=\"org.acegisecurity.providers.encoding.Md5PasswordEncoder\"/>

    <bean id=\"ems\" class=\"org.springframework.transaction.interceptor.TransactionProxyFactoryBean\">
    <property name=\"transactionManager\" ref=\"transactionManager\"/>        
    <property name=\"target\">            
        <bean class=\"info.ems.EMSImpl\" init-method=\"init\">
            <property name=\"dao\" ref=\"dao\"/>
            <property name=\"passwordEncoder\" ref=\"passwordEncoder\"/>
            <property name=\"localeList\" value=\"${ems.locales}\"/>
            <property name=\"releaseVersion\" value=\"${ems.version}\"/>
            <property name=\"releaseTimestamp\" value=\"${ems.timestamp}\"/>
            <property name=\"emsHome\" value=\"${ems.home}\"/>
        </bean>
    </property>       
    </bean>   

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

    <bean id=\"dataSource\" class=\"info.ems.datasource.DataSourceFactory\">
    <property name=\"driverClassName\" value=\"${database.driver}\"/>
    <property name=\"url\" value=\"${database.url}\"/>
    <property name=\"username\" value=\"${database.username}\"/>
    <property name=\"password\" value=\"${database.password}\"/>
    <property name=\"validationQuery\" value=\"${database.validationQuery}\"/>
    <property name=\"dataSourceJndiName\" value=\"${database.datasource.jndiname}\"/>
    </bean>     

    <tx:annotation-driven transaction-manager=\"transactionManager\" />

    <bean id=\"sessionFactory\" class=\"org.springframework.orm.hibernate3.LocalSessionFactoryBean\">
    <property name=\"dataSource\" ref=\"dataSource\"/>
    <property name=\"configLocation\">
            <value>/WEB-INF/hibernate.cfg.xml</value>
        </property>
    <property name=\"configurationClass\">
        <value>org.hibernate.cfg.AnnotationConfiguration</value>
        </property>        
    <property name=\"hibernateProperties\">
        <props>
            <prop key=\"hibernate.dialect\">${hibernate.dialect}</prop>        
            <prop key=\"hibernate.show_sql\">${hibernate.show_sql}</prop> 
            <prop key=\"hibernate.current_session_context_class\">org.hibernate.context.ThreadLocalSessionContext</prop>
        </props>
    </property>        
    </bean>

    <bean id=\"dao\" class=\"info.ems.hibernate.HibernateEMSDao\" init-method=\"createSchema\">
    <property name=\"hibernateTemplate\">
        <bean class=\"org.springframework.orm.hibernate3.HibernateTemplate\">
            <property name=\"sessionFactory\" ref=\"sessionFactory\"/>
        </bean>
    </property>        
    <property name=\"schemaHelper\">
        <bean class=\"info.ems.hibernate.SchemaHelper\">                                
            <property name=\"driverClassName\" value=\"${database.driver}\"/>
            <property name=\"url\" value=\"${database.url}\"/>
            <property name=\"username\" value=\"${database.username}\"/>
            <property name=\"password\" value=\"${database.password}\"/>
            <property name=\"hibernateDialect\" value=\"${hibernate.dialect}\"/>   
            <property name=\"dataSourceJndiName\" value=\"${database.datasource.jndiname}\"/>
        </bean>                
    </property>
    </bean>       
</beans>
服务层即EMS.java接口:
public interface EMS extends UserDetailsService {

    public void saveUser(User user);
}
及其实现EMSImpl.java:
@Service(\"emsImpl\")
@Transactional(readOnly=true)
public class EMSImpl implements EMS {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    @Qualifier(\"dao\")
    private EMSDao dao;


    //some other code


    @Transactional(readOnly=false)
    public void saveUser(User user) {

    }
}
接口dao是EMSDAO.java:
@Transactional(readOnly=true)
public interface EMSDao {

    public void saveUser(User user);
}
及其实现HibernateEMSDao.java
@Repository(\"EMSDao\")
public class HibernateEMSDao extends HibernateDaoSupport implements EMSDao {

    private final Logger logger = LoggerFactory.getLogger(getClass());  

    private SchemaHelper schemaHelper;

    public void setSchemaHelper(SchemaHelper schemaHelper) {
        this.schemaHelper = schemaHelper;
    }

    @Transactional(readOnly=false)
    public synchronized void saveUser(final User user) {        
        Session session = getSessionFactory().getCurrentSession();
        session.merge(user);
    }


    public void createSchema() {        
        try {
            getHibernateTemplate().find(\"from User user where user.id = 1\");
        } catch (Exception e) {
            logger.warn(\"expected database schema does not exist, will create. Error is: \" + e.getMessage());
            schemaHelper.createSchema();
            User admin = new User();
            admin.setUsername(\"admin\");
            admin.setName(\"Admin\");
            admin.setEmail(\"admin\");
            admin.setPassword(\"21232f297a57a5a743894a0e4a801fc3\");
            admin.setRoles(new HashSet<Role>(Arrays.asList(new Role(\"admin\", \"ADMINISTRATOR\"))));
            logger.info(\"inserting default admin user into database\");
            saveUser(admin);

            logger.info(\"schema creation complete\");                        
            return;
        }
        logger.info(\"database schema exists, normal startup\");              
    }
}
当我在插入用户管理员后部署战争时,出现此错误:
12:40:11,111 INFO  [STDOUT] 2011-05-30 12:40:11,111 [ScannerThread] INFO [info.ems.datasource.DataSourceFactory] - Attempting to shut down embedded HSQLDB database.
12:40:11,217 INFO  [STDOUT] 2011-05-30 12:40:11,217 [ScannerThread] INFO [info.ems.datasource.DataSourceFactory] - Embedded HSQLDB database shut down successfully.
12:40:11,220 INFO  [STDOUT] 2011-05-30 12:40:11,218 [ScannerThread] ERROR [org.springframework.web.context.ContextLoader] - Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name \'ems\' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Cannot create inner bean \'info.ems.EMSImpl#586f403e\' of type [info.ems.EMSImpl] while setting bean property \'target\'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name \'info.ems.EMSImpl#586f403e\' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Cannot resolve reference to bean \'dao\' while setting bean property \'dao\'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name \'dao\' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: merge is not valid without active transaction
我做错了什么,有什么想念的吗? 谢谢并恭祝安康。     
已邀请:
        这可能正在发生。您声明了方法
saveUser()
@Transactional,但是从
createSchema()
而不是
@Transactional
调用了它。因此,您实际上调用了非代理方法
saveUser()
,但它失败了。您最好在这里拍摄是使用
HibernateTemplate
。由于createSchema()是init方法,因此@Transactional可能无法在其上使用。 另请注意,界面上的“ 8”将无效。     

要回复问题请先登录注册