Hibernate thread-safe collections

那年仲夏 提交于 2021-02-07 08:56:53

问题


This is somewhat of a continuation of Hibernate session thread safety. All of the details apply here as well. In simplified terms, execution follows the pattern of:

1. Read entity
2. Do expensive, easily parallelizable work
3. Persist changes

The entities are all configured for eager loading, and the session is not accessed at all during 2.

The work involved in 2 requires infrequent modification of a persistent collection. This is what I have now:

synchronized (parentEntity) {
    parentEntity.getChildEntities().add(childEntity);
}

This works just fine, but I'm trying to "idiot-proof" this system and I'm looking for a way to move the concurrency control as far down into the persistence layer as I can. I've tried this in the dao:

@Transactional
public ParentEntity getParentEntityById(long id) {
    ParentEntity parent = ...;
    parent.setChildren(Collections.synchronizedSet(parent.getChildren()));
    return parent;
}

Which results in org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance...

Does anybody have a way to introduce thread-safety to hibernate collections, or some other clean way to control concurrent access and modification in a way that doesn't require polluting the business logic?

Update- Here is what I ended up doing, per Pace's suggestion:

@Transactional
public ParentEntity getParentEntityById(long id) {
    ParentEntity parent = ...;
    currentSession().evict(parent);
    parent.setChildren(Collections.synchronizedSet(parent.getChildren()));
    return parent;
}

After the work is done, I save all of the children and call currentSession().merge(parent). Works like a charm!


回答1:


  1. Read the entity
  2. Detach the entity
  3. Do expensive, easily parallelizable work
  4. Merge the entity
  5. Commit the transaction

If step 3 takes any significant amount of time then I would recommend simply:

  1. Open a session (could be read-only)
  2. Read the entity(ies)
  3. Close the session
  4. Do expensive, easily parallelizable work
  5. Open a new session
  6. Merge the entity(ies)
  7. Close the session

While detached/unattached you should be able to wrap the collections in thread safe collections. The merge should not care what collection implementation you have. I have not tested it however.



来源:https://stackoverflow.com/questions/20204897/hibernate-thread-safe-collections

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!