java - Usage of @Transactional with Spring Data custom methods -


i using spring data (via spring boot 1.3.3). repositories have custom method primary key. example:

@transactional(readonly=true) @repository public interface userrepository extends crudrepository<user, userid>, userrepositorycustom {   user findbyusername(string username); }  public interface userrepositorycustom {   userid nextid(); }  public class userrepositoryimpl implements userrepositorycustom {   public userid nextid() {     return new userid( uuid.randomuuid() );   } } 

is use of @transactional correct here? or need add @transactional userrepositoryimpl (possibly readonly set or not)?

the reason asking because unexplainable objectoptimisticlockingfailureexception

org.springframework.orm.objectoptimisticlockingfailureexception: object of class  [com.company.project.domain.game] identifier [gameid{id=7968c30b-838f-424c-bfef-838de7028def}]:  optimistic locking failed; nested exception  org.hibernate.staleobjectstateexception: row updated or deleted transaction  (or unsaved-value mapping incorrect) : [com.company.project.domain.game#gameid{id=7968c30b-838f-424c-bfef-838de7028def}] 

this happens during jmeter testing. altough methods called not change game entity in way.

i have added game entity debugging:

@preupdate public void preupdate() {     system.out.println("game updated!! version = " + version);     thread.dumpstack(); } 

this gives few times stack trace similar this:

java.lang.exception: stack trace     @ java.lang.thread.dumpstack(thread.java:1329)     @ com.company.project.domain.game.preupdate(game.java:85)     @ sun.reflect.nativemethodaccessorimpl.invoke0(native method)     @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62)     @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)     @ java.lang.reflect.method.invoke(method.java:497)     @ org.hibernate.jpa.event.internal.jpa.entitycallback.performcallback(entitycallback.java:47)     @ org.hibernate.jpa.event.internal.jpa.callbackregistryimpl.callback(callbackregistryimpl.java:112)     @ org.hibernate.jpa.event.internal.jpa.callbackregistryimpl.preupdate(callbackregistryimpl.java:76)     @ org.hibernate.jpa.event.internal.core.jpaflushentityeventlistener.invokeinterceptor(jpaflushentityeventlistener.java:68)     @ org.hibernate.event.internal.defaultflushentityeventlistener.handleinterception(defaultflushentityeventlistener.java:342)     @ org.hibernate.event.internal.defaultflushentityeventlistener.scheduleupdate(defaultflushentityeventlistener.java:293)     @ org.hibernate.event.internal.defaultflushentityeventlistener.onflushentity(defaultflushentityeventlistener.java:160)     @ org.hibernate.event.internal.abstractflushingeventlistener.flushentities(abstractflushingeventlistener.java:231)     @ org.hibernate.event.internal.abstractflushingeventlistener.flusheverythingtoexecutions(abstractflushingeventlistener.java:102)     @ org.hibernate.event.internal.defaultautoflusheventlistener.onautoflush(defaultautoflusheventlistener.java:61)     @ org.hibernate.internal.sessionimpl.autoflushifrequired(sessionimpl.java:1227)     @ org.hibernate.internal.sessionimpl.list(sessionimpl.java:1293)     @ org.hibernate.internal.queryimpl.list(queryimpl.java:103)     @ org.hibernate.jpa.internal.queryimpl.list(queryimpl.java:573)     @ org.hibernate.jpa.internal.queryimpl.getsingleresult(queryimpl.java:495)     @ org.hibernate.jpa.criteria.compile.criteriaquerytypequeryadapter.getsingleresult(criteriaquerytypequeryadapter.java:71)     @ org.springframework.data.jpa.repository.query.jpaqueryexecution$singleentityexecution.doexecute(jpaqueryexecution.java:206)     @ org.springframework.data.jpa.repository.query.jpaqueryexecution.execute(jpaqueryexecution.java:78)     @ org.springframework.data.jpa.repository.query.abstractjpaquery.doexecute(abstractjpaquery.java:100)     @ org.springframework.data.jpa.repository.query.abstractjpaquery.execute(abstractjpaquery.java:91)     @ org.springframework.data.repository.core.support.repositoryfactorysupport$queryexecutormethodinterceptor.doinvoke(repositoryfactorysupport.java:462)     @ org.springframework.data.repository.core.support.repositoryfactorysupport$queryexecutormethodinterceptor.invoke(repositoryfactorysupport.java:440)     @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179)     @ org.springframework.data.projection.defaultmethodinvokingmethodinterceptor.invoke(defaultmethodinvokingmethodinterceptor.java:61)     @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179)     @ org.springframework.transaction.interceptor.transactioninterceptor$1.proceedwithinvocation(transactioninterceptor.java:99)     @ org.springframework.transaction.interceptor.transactionaspectsupport.invokewithintransaction(transactionaspectsupport.java:281)     @ org.springframework.transaction.interceptor.transactioninterceptor.invoke(transactioninterceptor.java:96)     @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179)     @ org.springframework.dao.support.persistenceexceptiontranslationinterceptor.invoke(persistenceexceptiontranslationinterceptor.java:136)     @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179)     @ org.springframework.data.jpa.repository.support.crudmethodmetadatapostprocessor$crudmethodmetadatapopulatingmethodinterceptor.invoke(crudmethodmetadatapostprocessor.java:131)     @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179)     @ org.springframework.aop.interceptor.exposeinvocationinterceptor.invoke(exposeinvocationinterceptor.java:92)     @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179)     @ org.springframework.aop.framework.jdkdynamicaopproxy.invoke(jdkdynamicaopproxy.java:208)     @ com.sun.proxy.$proxy141.findbyusername(unknown source)     @ com.company.project.service.userserviceimpl.findbyusername(userserviceimpl.java:117)     @ com.company.project.service.userserviceimpl.subtractcredits(userserviceimpl.java:143)     @ sun.reflect.nativemethodaccessorimpl.invoke0(native method)     @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62)     @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)     @ java.lang.reflect.method.invoke(method.java:497)     @ org.springframework.aop.support.aoputils.invokejoinpointusingreflection(aoputils.java:302)     @ org.springframework.aop.framework.reflectivemethodinvocation.invokejoinpoint(reflectivemethodinvocation.java:190)     @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:157)     @ org.springframework.transaction.interceptor.transactioninterceptor$1.proceedwithinvocation(transactioninterceptor.java:99)     @ org.springframework.transaction.interceptor.transactionaspectsupport.invokewithintransaction(transactionaspectsupport.java:281)     @ org.springframework.transaction.interceptor.transactioninterceptor.invoke(transactioninterceptor.java:96)     @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179)     @ org.springframework.aop.framework.jdkdynamicaopproxy.invoke(jdkdynamicaopproxy.java:208)     @ com.sun.proxy.$proxy154.subtractcredits(unknown source)     @ com.company.project.service.gameserviceimpl.subtractcreditsforplacedshotsandsave(gameserviceimpl.java:703)     @ com.company.project.service.gameserviceimpl.placeshotsongamewhengameisopen(gameserviceimpl.java:641)     @ com.company.project.service.gameserviceimpl.placeshotsongame(gameserviceimpl.java:629)     @ com.company.project.service.gameserviceimpl.placeshots(gameserviceimpl.java:281)     @ sun.reflect.nativemethodaccessorimpl.invoke0(native method)     @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62)     @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43)     @ java.lang.reflect.method.invoke(method.java:497)     @ org.springframework.aop.support.aoputils.invokejoinpointusingreflection(aoputils.java:302)     @ org.springframework.aop.framework.reflectivemethodinvocation.invokejoinpoint(reflectivemethodinvocation.java:190)     @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:157)     @ org.springframework.transaction.interceptor.transactioninterceptor$1.proceedwithinvocation(transactioninterceptor.java:99)     @ org.springframework.transaction.interceptor.transactionaspectsupport.invokewithintransaction(transactionaspectsupport.java:281)     @ org.springframework.transaction.interceptor.transactioninterceptor.invoke(transactioninterceptor.java:96)     @ org.springframework.aop.framework.reflectivemethodinvocation.proceed(reflectivemethodinvocation.java:179)     @ org.springframework.aop.framework.jdkdynamicaopproxy.invoke(jdkdynamicaopproxy.java:208)     @ com.sun.proxy.$proxy164.placeshots(unknown source)     @ com.company.project.controller.front.frontgamecontroller.placeshots(frontgamecontroller.java:180) 

looking @ stuff relevant app, see this:

java.lang.exception: stack trace     @ java.lang.thread.dumpstack(thread.java:1329)     @ com.company.project.domain.game.preupdate(game.java:85)     @ com.company.project.service.userserviceimpl.findbyusername(userserviceimpl.java:117)     @ com.company.project.service.userserviceimpl.subtractcredits(userserviceimpl.java:143)     @ com.company.project.service.gameserviceimpl.subtractcreditsforplacedshotsandsave(gameserviceimpl.java:703)     @ com.company.project.service.gameserviceimpl.placeshotsongamewhengameisopen(gameserviceimpl.java:641)     @ com.company.project.service.gameserviceimpl.placeshotsongame(gameserviceimpl.java:629)     @ com.company.project.service.gameserviceimpl.placeshots(gameserviceimpl.java:281)     @ com.company.project.controller.front.frontgamecontroller.placeshots(frontgamecontroller.java:180) 

so somehow, findbyusername seems trigger update unrelated entity game?

fyi: gameserviceimpl#placeshots has @transactional annotation. tried adding such annotation on controller method, did not change anything.

the problem not in use of @transactional.

i using custom hibernate usertype stores object json using jackson library. game object has field uses usertype. class of field did not implement equals(). result, hibernate assumed object changed , issued save on game object.

after implementing equals(), problem went away.


Comments

Popular posts from this blog

html - Styling progress bar with inline style -

java - Oracle Sql developer error: could not install some modules -

How to use autoclose brackets in Jupyter notebook? -