Supposed that I have this data on a table 'X' :
ID UpdatedDate ParentID
001 2015-01-01 1
002 1
003 1
The code is (I simplified the code) :
...
@Autowired
private XDao xDao;
private void createTransaction(ParentData parentData) {
List<XData> xDataList = xDao.getDataByParentIdAndUpdatedDateIsNull(parentData.getId());
XData xData = null;
// Then we get only the first row of the list
if(xDataList != null && xDataList.size() > 0) {
xData = xDataList.get(0);
} else {
return;
}
// Another transaction
...
// Then we update the UpdatedDate
xData.setUpdatedDate(new Date());
xDao.saveAndFlush(xData);
// And we call the createTransaction again until there is no more xData with a null UpdatedDate on a Parent ID
createTransaction(parentData);
}
But what I get is a never ending process, while I check the db, it's always afflicted each other data on the same parent id. So the db is something like :
The first iteration :
ID UpdatedDate ParentID
001 2015-01-01 1
002 2015-02-02 1
003 1
The 2nd:
ID UpdatedDate ParentID
001 2015-01-01 1
002 1
003 2015-02-02 1
The 3rd:
ID UpdatedDate ParentID
001 2015-01-01 1
002 2015-02-02 1
003 1
etc. What's wrong?
This is the getDataByParentIdAndUpdatedDateIsNull class (I simplified the code) :
...
public static final String GET_DATA_BY_PARENTIDANDUPDATEDDATEISNULL =
"SELECT o FROM XData o " +
"WHERE o.parentData.parentId = ?1 " +
" AND o.updatedDate IS NULL";
@Query(GET_DATA_BY_PARENTIDANDUPDATEDDATEISNULL)
public List<XData> getDataByParentIdAndUpdatedDateIsNull(Long parentId);
Can you share,
1) definition of
XDao
2) what is your underlying data store
3) Are you using any of the ORM framework
4) are you using explicit
@Transactional
on your Repository/Service or thetx:annotation-driven
?The behavior would be different based on the combination of the above, but my guess would be either with service transaction boundary confusing with that of store OR Since the
@Transactional
mechanism is based on proxies, only 'external' method calls coming in through the proxy will be intercepted and your recursive call will not be going through the same AOP you might have set up for yourcreateTransaction
method.Having said that, is it not possible to do something like this, instead of recursion: