Getting below exception while updating entry in the cache while establishing Many to Many relation.
org.apache.geode.cache.UnsupportedOperationInTransactionException: Expected size of 1 {[/__PR/_B__User_101]} for target=192.168.1.2(cacheServer2:7756)<v1>:41001 during a distributed transaction but got 2 {[[], [DistTxThinEntryState: ,regionVersion=2 ,tailKey=440 ,memberID=null]]}
at org.apache.geode.internal.cache.DistTXStateProxyImplOnCoordinator.populateEntryEventMap(DistTXStateProxyImplOnCoordinator.java:576)
at org.apache.geode.internal.cache.DistTXStateProxyImplOnCoordinator.doPrecommit(DistTXStateProxyImplOnCoordinator.java:484)
at org.apache.geode.internal.cache.DistTXStateProxyImplOnCoordinator.commit(DistTXStateProxyImplOnCoordinator.java:88)
at org.apache.geode.internal.cache.TXManagerImpl.commit(TXManagerImpl.java:426)
at com.trendcore.cache.peertopeer.service.UserServiceImpl.attachRoleToUser(UserServiceImpl.java:108)
at com.trendcore.cache.peertopeer.CacheApplication.attachRoleToUser(CacheApplication.java:121)
Cache Configuration -> It's Peer to Peer configration with 2 regions.
Properties properties = new Properties();
properties.setProperty("locators", "localhost[13489]");
properties.setProperty("mcast-address", "224.0.0.0");
properties.setProperty("mcast-port", "0");
properties.setProperty(NAME, "cacheServer1");
CacheFactory cacheFactory = new CacheFactory(this.cacheConfiguration);
cache = cacheFactory.create();
User Region
RegionFactory<Long, User> regionFactory = this.cache.createRegionFactory(RegionShortcut.PARTITION);
userRegion = regionFactory.create(USER_REGION);
Role Region
RegionFactory<Long, Role> regionFactory = this.cache.createRegionFactory(RegionShortcut.PARTITION);
roleRegion = regionFactory.create(ROLE_REGION);
User model resides in User region
public class User implements Serializable{
private Long id;
private String username;
private Map<Long,Object> roles;
//Getters , Setters
public void addRole(Long roleId) {
roles.put(roleId,null);
}
}
Role model resides in Role region
public class Role implements Serializable {
private Long id;
private String roleName;
//getters , setters
}
Users and roles are inserted in the respective regions using below code.
public void insertUser(User user) {
CacheTransactionManager cacheTransactionManager = cache.getCacheTransactionManager();
try {
cacheTransactionManager.begin();
userRegion.put(user.getId(), user);
cacheTransactionManager.commit();
} catch (Exception e) {
cacheTransactionManager.rollback();
}
}
public void insertRole(Role role) {
CacheTransactionManager cacheTransactionManager = cache.getCacheTransactionManager();
try {
cacheTransactionManager.begin();
roleRegion.put(role.getId(), role);
cacheTransactionManager.commit();
} catch (Exception e) {
cacheTransactionManager.rollback();
}
}
When any roleIds are put in existing cache user object then above exception is thrown.
public void attachRoleToUser(Long userId, Long roleId) {
Region<Long, User> userRegion = cache.getRegion(USER_REGION);
Region<Long, Role> roleRegion = cache.getRegion("Role");
CacheTransactionManager cacheTransactionManager = cache.getCacheTransactionManager();
try {
cacheTransactionManager.setDistributed(true);
cacheTransactionManager.begin();
Role role = roleRegion.get(roleId);
if (role != null) {
User user = userRegion.get(userId);
user.addRole(role.getId());
userRegion.put(userId,user);
}
cacheTransactionManager.commit();
} catch (Exception e) {
try {
cacheTransactionManager.rollback();
}catch (Exception rbe){
}
throw new RuntimeException(e);
}
}
Any guidance in this case will be appreciated.