我有一个集成测试,我正在测试一些在我的两个域对象之间运行的业务逻辑方法。
因为我有多个测试创建相同的对象集以在不同条件下运行我的测试,所以我在设置中创建域对象并在清理中删除它们。
但是,我org.springframework.dao.DuplicateKeyException
第二次尝试保存此对象,其中我对该对象所做的唯一更改不是唯一字段。根据下面的消息,似乎先前测试的版本可能会以某种方式徘徊。
如果我不使用设置和清理,而是在每个测试方法的主体中创建所有对象,则测试通过。
相关代码和错误如下:
import grails.test.mixin.integration.Integration
import grails.transaction.*
import spock.lang.*
import com.grapevine.negotiator2.DomainFactory
@Integration
@Rollback
class AgentSpec extends Specification {
User u
Agent a
Buyer b
User u2
def setup() {
//make two users
u2 = DomainFactory.makeUser("Pancho", "password", E.SpringAuthority.ROLE_USER)
u =DomainFactory.makeUser("Gorman","password",E.SpringAuthority.ROLE_USER)
//make a buyer
b = DomainFactory.makeBuyer("Sam Jones")
b.scaleFear = 0.0
b.scaleGreed = 0.0
b.save()
//make an agent
a = DomainFactory.makeAgent(u)
}
def cleanup() {
DomainFactory.killUser(u)
DomainFactory.killUser(u2)
b.delete(flush: true)
a.delete(flush:true)
}
void "TestforBadReputation"() {
given: "An agent with bad reputation"
a.reputation=-5.1
expect: "An agent with a <-5 reputation to be rejected by any buyer"
a.validate()
a.save()
b.respondToRepresentationRequest(a)==E.BuyerAgencyResponse.BadReputation
}
void "TestforAlreadyHasAgent"() {
given: "An buyer who already has an agent"
b.agent = a
b.save()
a.reputation=5
expect: "Buyer rejects agency request"
a.validate()
a.save()
b.respondToRepresentationRequest(a)== E.BuyerAgencyResponse.AlreadyRepresented
}
}
错误:
org.springframework.dao.DuplicateKeyException: A different object with the same
identifier value was already associated with the session : [com.grapevine.negotiator2.Agent#13];
nested exception is org.hibernate.NonUniqueObjectException: A different object
with the same identifier value was already associated with the session : [com.grapevine.negotiator2.Agent#13]
at org.springframework.orm.hibernate5.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:259)
at org.grails.orm.hibernate.GrailsHibernateTemplate.convertHibernateAccessException(GrailsHibernateTemplate.java:661)
at org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:247)
at org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:187)
at org.grails.orm.hibernate.GrailsHibernateTemplate.execute(GrailsHibernateTemplate.java:110)
at org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.performSave(AbstractHibernateGormInstanceApi.groovy:241)
at org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.save(AbstractHibernateGormInstanceApi.groovy:158)
at org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:116)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:98)
at com.grapevine.negotiator2.AgentSpec.$tt__$spock_feature_0_4(AgentSpec.groovy:98)
at com.grapevine.negotiator2.AgentSpec.TestforBuyerAcceptance2_closure7(AgentSpec.groovy)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at grails.transaction.GrailsTransactionTemplate$1.doInTransaction(GrailsTransactionTemplate.groovy:70)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.executeAndRollback(GrailsTransactionTemplate.groovy:67)
at com.grapevine.negotiator2.AgentSpec.TestforBuyerAcceptance2(AgentSpec.groovy)
原因:org.hibernate.NonUniqueObjectException:具有相同标识符值的不同对象已与会话相关联:org.hibernate.engine.internal.StatefulPersistenceContext.checkUniqueness(StatefulPersistenceContext. java:642) 在 org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsDetached(DefaultSaveOrUpdateEventListener.java:227) 在 org.hibernate.event.internal 的 org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.performUpdate(DefaultSaveOrUpdateEventListener.java:284) .DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:92) 在 org.grails.orm.hibernate.support 的 org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)。ClosureEventTriggeringInterceptor.onSaveOrUpdate(ClosureEventTriggeringInterceptor.java:81) at org.hibernate.internal.SessionImpl.fireSaveOrUpdate(SessionImpl.java:651) at org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:643) at org.hibernate.internal .SessionImpl.saveOrUpdate(SessionImpl.java:638) at org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.performSave_closure3(AbstractHibernateGormInstanceApi.groovy:242) at groovy.lang.Closure.call(Closure.java:414) at org.grails。 orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:243) ... 还有 14 个643) 在 org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:638) 在 org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.performSave_closure3(AbstractHibernateGormInstanceApi.groovy:242) 在 groovy.lang.Closure.call(Closure.java :414) 在 org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:243) ... 还有 14 个643) 在 org.hibernate.internal.SessionImpl.saveOrUpdate(SessionImpl.java:638) 在 org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.performSave_closure3(AbstractHibernateGormInstanceApi.groovy:242) 在 groovy.lang.Closure.call(Closure.java :414) 在 org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:243) ... 还有 14 个