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