为什么getHibernateTemplate().delete(实体)失败?
代码如下: //冬眠模型为什么getHibernateTemplate().delete(实体)失败?,hibernate,spring,transactions,Hibernate,Spring,Transactions,代码如下: //冬眠模型 @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
@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;
}
}
//道层
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");
}
//弹簧配置
<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>
我没有主意。强烈建议为您的对象实现
equals()
和hashCode()
,因为您似乎对每个操作使用单独的会话
看
更新
基于Spring的单元测试似乎没有提交事务。默认情况下,Spring测试框架将回滚它启动的事务。如果您使用Spring事务测试,默认情况下,事务将在测试后回滚。不确定这是否是问题所在。我建议启用Hibernate日志记录,看看是否生成了delete语句。我们在JUnits中使用Spring for DI,但我在Spring配置中找不到任何与使测试具有事务性相关的内容。基本测试类被注释为@TestExecutionListeners({DependencyInjectionTestExecutionListener.class}),但是文档没有提到让测试成为事务性的。啊,就是这样!我们的基本测试类派生自AbstractTransactionalJUnit4SpringContextTests。千万!顺便说一下,在您的示例中,我没有看到任何可以实例化您的服务的内容。所以,您可能希望将断点或转储堆栈放在您的服务方法中,以查看它是否确实被aspectj代理!
public void addContact(Contact contact) {
try {
getHibernateTemplate().save(contact);
} catch (DataAccessException e) {
log.error(e.getMessage());
throw e;
}
}