Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » EclipseLink » Eclipselink reverts merged entities(When trying to get entities after merge, changes are reverted)
Eclipselink reverts merged entities [message #1770939] Fri, 18 August 2017 23:27 Go to next message
Vitalyi Brodetskyi is currently offline Vitalyi BrodetskyiFriend
Messages: 1
Registered: August 2017
Junior Member
Hi all. We are using eclipselink version 2.6.2. Here is part of code which works incorrectly:
if (serviceConfigEntity.getGroupId() == null) {
      Collection<String> configTypes = serviceConfigTypes.get(serviceName);
      List<ClusterConfigEntity> enabledConfigs = clusterDAO.getEnabledConfigsByTypes(clusterId, configTypes);
      for (ClusterConfigEntity enabledConfig : enabledConfigs) {
        enabledConfig.setSelected(false);
        clusterDAO.merge(enabledConfig);
      }

      for (ClusterConfigEntity configEntity : serviceConfigEntity.getClusterConfigEntities()) {
        configEntity.setSelected(true);
        clusterDAO.merge(configEntity);
      }

Here you can see part of code which updates ClusterConfigEntities. First loop set field "selected" to "false". In next loop we are getting actual config entities and set "selected" to "true". These two lists have same antities. So, we are getting such situation, when in first loop entity was changed (by merge), but in second loop, using "getClusterConfigEntities" method we are getting same entity with reverted changes. I've spent some time on debug and find code in eclipselink which reverts merge changes. Here it is:
UnitOfWorkImpl.registerExistingObject(...)
            //bug3659327
            //fetch group manager control fetch group support
            if (descriptor.hasFetchGroupManager()) {
                //if the object is already registered in uow, but it's partially fetched (fetch group case)	
                if (descriptor.getFetchGroupManager().shouldWriteInto(objectToRegister, registeredObject)) {
                    //there might be cases when reverting/refreshing clone is needed.
                    descriptor.getFetchGroupManager().writePartialIntoClones(objectToRegister, registeredObject, this.getBackupClone(registeredObject, descriptor), this);
                }
            }

And here is method which check if we need reverting/refreshing clone:
public boolean shouldWriteInto(Object cachedObject, Object clone) {
        FetchGroup fetchGroupInTarg = ((FetchGroupTracker)clone)._persistence_getFetchGroup();
        if (fetchGroupInTarg != null) {
            FetchGroup fetchGroupInSrc = ((FetchGroupTracker)cachedObject)._persistence_getFetchGroup();

            //should write if target's fetch group is not a superset of that of the source, 
            //or if refresh is required, should always write (either refresh or revert) data from the cache to the clones.
            return !fetchGroupInTarg.isSupersetOf(fetchGroupInSrc) || ((FetchGroupTracker) cachedObject)._persistence_shouldRefreshFetchGroup();
        }
        return false;
    }

In our case this method return "true" because of _persistence_shouldRefreshFetchGroup(). In that case we don't need refresh groups. So, do you know any workaround or solution to fix that?
Re: Eclipselink reverts merged entities [message #1771268 is a reply to message #1770939] Wed, 23 August 2017 14:30 Go to previous message
Chris Delahunt is currently offline Chris DelahuntFriend
Messages: 1275
Registered: July 2009
Senior Member
I don't understand your code or what you are doing exactly, and it isn't clear exactly what you are seeing and you haven't shown the transaction. From the code, my first thought is that these entities are different instances - that the serviceConfigEntity is read from one EntityManager that is independent from the one you are using for the clusterDAO.getEnabledConfigsByTypes and clusterDAO.merge operations. EntityManagers are meant to represent separate transactions, and so would not see changes made in other EntityManagers unless they get refreshed.

If this is not the case, and the instances are the same object (==), then you need to show more details on the fetch groups and queries used to load the serviceConfigEntity and ClusterConfigEntity instances, as well as the getClusterConfigEntities mapping. That a fetch group refreshes the instance when it is triggered is a known issue (https://bugs.eclipse.org/bugs/show_bug.cgi?id=371743) but only for basic properties, not reference mappings.
Previous Topic:Getting NullPointerException in FullIdentityMap.getCacheKey() upon query.getResultList()
Next Topic:eclipselink-2.2.0 link IN Clause
Goto Forum:
  


Current Time: Fri Dec 15 18:13:14 GMT 2017

Powered by FUDForum. Page generated in 0.01900 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software