Hibernate / Spring回滚插入没有错误

时间:2011-02-02 03:46:28

标签: java hibernate spring

我有2个类,Foo和FooType,其中FooType在数据库中只有3行,代表3种可能的类型。我在Hibernate中映射FooType,但ID和描述字段除外。在FooType hbm文件中没有映射回Foo。

在Foo中,我有一个多对一的映射,因为每个Foo都需要一个Type。

<hibernate-mapping>
    <class name="com.blah.domain.Foo" table="foos" lazy="false">
        <id name="id" type="int">
            <column name="id" />
            <generator class="identity" />
        </id>
    <many-to-one name="type" class="com.blah.domain.FooType" column="type" not-null="true" unique="false" update="false" fetch="join"/>
    </class>
</hibernate-mapping>

这是我的Spring配置的相关位

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory"><ref local="sessionFactory"/></property>
</bean>
<bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configLocation">
    <value>WEB-INF/hibernate.cfg.xml</value>
</property>
    <property name="mappingResources">
        <list>
            <value>com/secretry/domain/Foo.hbm.xml</value>
            <value>com/secretry/domain/FooType.hbm.xml</value>
        </list>
    </property>
</bean>

我认为这是正确的,但如果没有请求帮助。我有一个使用HibernateDaoSupport进行交易的FooDao。

public class FoonDao extends HibernateDaoSupport implements IFooDao {

    private IFooTypeDao fooTypeDao;

    @Override
    public Foo createFoo(String name, String description, int fooTypeId) {

        FooType type = fooTypeDao.getFooType(fooTypeId);
        Foo newFoo = new Foo(name, description, type);

        try {
            getHibernateTemplate().save(newFoo);
        }
        catch(Exception e) {
            logger.error("ERROR: ", e);
            return null;
        }

        return newFoo;
    }
}

当我运行createFoo时,我没有看到任何错误,但在我的MySQL日志中,我看到Insert语句紧跟着rollback。我已经为Hibernate打开了完整的日志记录,但我没有看到任何让我感到错误的错误。当我从日志中复制插入并在mysql中手动运行时,它可以正常工作,这可能是最令人困惑的事情。

我是Hibernate的新手,所以我想这可能是我在做多对一映射时遇到的问题,但我无法想象我的生活。任何有关我可能做错的问题或方向的帮助都将受到大力赞赏。感谢。

2 个答案:

答案 0 :(得分:2)

您是否在“IFooDao”界面上有@Transactional注释

答案 1 :(得分:0)

提到HibernateTemplate不再是正确的做事方式,以及@Transactional注释的建议,我想出了以下似乎有效的方法。我没有声称这是最好的或唯一的方式,但它的工作原理,我想为未来的读者保留这个配置的记录。

请注意,使用HibernateTemplate的“老方法”是书中描述的方式“Spring in Action 2nd Edition”,但这种新方式主要来自第3版

Spring config

<bean id="FooDao" class="com.foo.dao.FooDao" >
  <constructor-arg name="sessionFactory" ref="sessionFactory"/>
</bean>

  <tx:annotation-driven />

  <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

  <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory"><ref local="sessionFactory"/></property>
  </bean>
  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="configLocation">
        <value>WEB-INF/hibernate.cfg.xml</value>
            </property>
  <property name="packagesToScan">
    <list>
        <value>com.secretry.domain</value>
    </list>
  </property>

  <property name="mappingResources">
    <list>
    <value>com/secretry/domain/Mission.hbm.xml</value>
    <value>com/secretry/domain/MissionType.hbm.xml</value>
    <value>com/secretry/domain/Spy.hbm.xml</value>
    <value>com/secretry/domain/CompletedMission.hbm.xml</value>
    </list>
  </property>
</bean>

DAO的Java代码我用来从Hibernate获取对象。

@Repository
@Transactional
public class FooDao implements IFooDao {

    private SessionFactory sessionFactory;

    @Autowired
    public FooDao(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public FooDao() {
    }

    private Session currentSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    @Cacheable(cacheName="secretryCache")
    public Foo getFoo(int id) {

        return (Foo)currentSession().load(Foo.class, id);

    }
}

确保从hibernate配置文件中删除以下内容

  <property name="current_session_context_class">thread</property>