Eclipselink reverts merged entities [message #1770939] |
Fri, 18 August 2017 19:27  |
Eclipse User |
|
|
|
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 10:30  |
Eclipse User |
|
|
|
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.
|
|
|
Powered by
FUDForum. Page generated in 0.03304 seconds