为什么getHibernateTemplate()。delete(entity)失败了?

时间:2011-06-18 21:53:42

标签: hibernate spring transactions

以下是代码:

// 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;
    }
}

我没有想法。

1 个答案:

答案 0 :(得分:1)

强烈建议您为对象实施equals()hashCode(),因为您似乎为每个操作使用单独的会话。

请参阅http://docs.jboss.org/hibernate/core/3.3/reference/en/html/persistent-classes.html#persistent-classes-equalshashcode


更新

看来你的基于Spring的单元测试不会提交事务。默认情况下,Spring测试框架将回滚它启动的事务。