我正在使用 Spring = 3.2.3.RELEASE 和 Hibernate-annotations = 3.5.6-Final
我有豆子:
@Entity
public class Step implements Serializable, Comparable<Step> {
private static final long serialVersionUID = -5345848109844492261L;
@Id
@GeneratedValue
private Integer id;
@Column
private String description;
@Column(nullable = false)
private boolean active;
@Column(nullable = false)
private int stepOrder;
@Column(nullable = false)
private String command;
@ManyToOne
@JoinColumn(name = "elementID")
private Element element;
@Column
private String arg1;
@Column
private String arg2;
@ManyToOne
@JoinColumn(name = "testCaseID", nullable = false)
private TestCase testCase;
@ManyToOne
@JoinColumn(name = "releaseID", nullable = false)
private ReleaseEntity releaseEntity;
@ManyToOne
@JoinColumn(name = "updatedBy", nullable = false)
private User updatedBy;
@Temporal(TemporalType.TIMESTAMP)
@Column(columnDefinition = "timestamp", insertable = false, updatable = false)
@Generated(GenerationTime.ALWAYS)
private Date updatedDate;
@Column(nullable = false)
private boolean deleted;
.....
getters/ setters , equals / hashCode
我有 dao 坚持这个实体:
@Repository("StepDAO")
@Transactional
public class StepDAOMysql extends BaseDAOMysql implements StepDAO
{
@Override
public void delete(Step step)
{
if (hasHistory(step))
{
List<?> listToDelete = hibernateTemplate.find(
"from StepHistory st where st.step=?", step);
hibernateTemplate.deleteAll(listToDelete);
}
hibernateTemplate.evict(step);
hibernateTemplate.delete(step);
}
@Override
@Transactional(readOnly = true)
public boolean hasHistory(Step step)
{
return !CollectionUtils.isEmpty(hibernateTemplate.find(
"from StepHistory st where st.step=?", step));
}
当我尝试删除我的 DAO 时,我得到
org.springframework.dao.DuplicateKeyException: a different object with the same identifier value was already associated with the session: [com.livenation.automation.bean.Step#1]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.livenation.automation.bean.Step#1]
其实我很困惑。谷歌搜索了很多关于重复异常的信息,所有帖子都是关于 saveOrUpdate 期间的重复异常,但没有人在 delete 上遇到它。但无论如何,我插入建议的解决方案 - 驱逐方法并没有帮助。可能是hibernate和spring之间映射异常的一些错误?(我之前在其他项目中看到过这样的问题)
编辑:似乎问题仅与在测试上下文中执行此方法有关,如果在生产中执行它不会发生异常,则测试代码非常简单
@Test
public void canDeleteStepWithHistory()
{
linkedStep.setArg1(getRandomString());
dao.saveOrUpdate(linkedStep); // in line above we change value of linkedStep , DAO will detect this and will create appropriate StepHistory object that linked with linkedStep . This is main goal ofg test check that DAO can delete such object
dao.delete(linkedStep);
Step fromDB = dao.getById(linkedStep.getId());
Assertions.assertThat(fromDB).isNull();
}
使用 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("/test-dispatcher.xml") 执行测试