【发布时间】:2017-12-20 12:33:08
【问题描述】:
我有一部分程序以并行方式与另一个系统实现同步。每个同步过程都会打开新事务。同步对象将映射到某些数据并持久化。 将要映射的对象的数据可以在之前持久化,并且可以在同步时持久化。
我的持久层提供级联操作,所以我不关心所有依赖项的持久化。
问题
在映射对象之前没有持久化,在同步的时候会被保存在不同的线程中同时出现休眠异常:
org.springframework.dao.DataIntegrityViolationException: A different object with the same identifier value was already associated with the session : [my.project.entity.CrmCaseLink#27];
nested exception is javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [my.project.entity.CrmCaseLink#27]
我尝试解决问题没有帮助
1.
我尝试使用缓存,在那里我可以为不同的线程获得相同的CrmCaseLink,但这并没有解决我的问题。
2.
我又试了一次
@CacheConfig(cacheNames = Constants.CRM_CASE_LINK_CACHE, cacheManager = Constants.GUAVA_CACHE_MANAGER)
@Service
public class CrmCaseLinkService {
private static final Logger LOGGER = LogManager.getLogger(CrmCaseLinkService.class);
@Autowired
private CrmCaseLinkRepository crmCaseLinkRepository;
@Cacheable(key = "#id")
@Transactional(propagation = Propagation.REQUIRES_NEW)
public synchronized CrmCaseLink findOne(Long id) {
LOGGER.debug("trace loading crm case link by specified id: {}", id);
return Optional.ofNullable(crmCaseLinkRepository.findOne(id))
.orElseGet(() -> crmCaseLinkRepository.save(new CrmCaseLink(id)));
}
}
问题
为什么这里的缓存是错误的?我希望hiberate 能够在不同的事务中管理相同的非持久化实体。我确信在单独的 spring bean 中具有新事务的缓存解决方案是无可争议的解决方案,但它也对我没有帮助。
其他细节
java8、spring、spring data jpa、postgres、hibernate5、码头容器
【问题讨论】:
标签: java spring multithreading hibernate jpa