以下是代码:
// Hibernate模型
@Entity
@Table(name="contact")
public class Contact {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
@Column(name = "contact_id")
private Long id;
@Column(name="contact_ref_id")
private String contactRefId;
@Column(name="first_name")
private String firstName;
@Column(name="last_name")
private String lastName;
@ManyToOne
@JoinColumn(name="app_user_id")
/** user whose contact list owns this contact */
private AppUser appUser;
public Long getId() {
return id;
}
public void setId(Long 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;
}
/**
* @return AppUser who owns contact list this contact belongs to
*/
public AppUser getAppUser() {
return appUser;
}
public void setAppUser(AppUser appUser) {
this.appUser=appUser;
}
public String getContactRefId() {
return contactRefId;
}
public void setContactRefId(String contactRefId) {
this.contactRefId=contactRefId;
}
}
// DAO图层
private Criteria createCriteria() {
return getHibernateTemplate().getSessionFactory().getCurrentSession().createCriteria(Contact.class);
}
public void deleteContact(String contactRefId) {
Criteria criteria = createCriteria();
criteria.add(Restrictions.eq("contactRefId", contactRefId));
Contact contact = (Contact)criteria.uniqueResult();
try {
contact = getHibernateTemplate().merge(contact);
getHibernateTemplate().delete(contact);
} catch (DataAccessException e) {
log.error(e.getMessage());
throw e;
}
}
//服务层
public void deleteContact(String contactRefId) {
contactDao.delete(contactRefId);
}
//单元测试
@Test
public void testDeleteContact() {
contactService.deleteContact("fe43b43a-d77f-45ce-b024-bb6e93264a69");
}
// Spring config
<beans>
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="model.hibernate"/>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.MySQLInnoDBDialect
hibernate.query.substitutions=true 'Y', false 'N'
hibernate.cache.use_second_level_cache=true
hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
</value>
</property>
</bean>
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="contactsDao" class="ContactDaoHibernate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* service..*.*(..))" order="0"/>
</aop:config>
<!-- Enable @Transactional support -->
<tx:annotation-driven/>
<!-- Enable @AspectJ support -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
</beans>
当我触发测试方法时,不会抛出任何异常,但不会删除db中的行。通过criteria.uniqueResult()从db中获取后,调试器中的Contact对象的检查显示已获取完整且正确的对象。虽然合并调用可能看起来不必要,但我这样做是为了查看是否存在使用错误的会话进行删除的问题。
因此看起来在事务中没有调用delete,尽管Spring配置很简单,我没有看到任何潜在的问题。最令人困惑的是这个DAO代码有效:
public void addContact(Contact contact) {
try {
getHibernateTemplate().save(contact);
} catch (DataAccessException e) {
log.error(e.getMessage());
throw e;
}
}
我没有想法。
答案 0 :(得分:1)
强烈建议您为对象实施equals()
和hashCode()
,因为您似乎为每个操作使用单独的会话。
更新
看来你的基于Spring的单元测试不会提交事务。默认情况下,Spring测试框架将回滚它启动的事务。