Spring JPA: как проверить, принадлежит ли объект текущей транзакции JPA? - PullRequest
0 голосов
/ 09 мая 2020

Мне нужна возможность проверить, принадлежит ли Entity к текущей текущей транзакции. У меня есть кеш сущностей JPA как локальный кеш потока. Почти всегда, когда есть одна @Transaction, нет проблем, когда один и тот же поток вызывает несколько раз, чтобы сэкономить на службе, а НЕ вложенный @Trasaction (Propagation.REQUIRES_NEW) (то есть, когда у вас есть вложенные транзакции) в одном потоке, это не работает. Есть ли способ проверить, принадлежит ли объект JPA (MyExpesiveEntity) текущей текущей транзакции?

        ThreadLocal<Map<Long,MyExpesiveEntity>> cache = new ThreadLocal<Map<Long,MyExpesiveEntity>>()
        @Entity('MyExpesiveEntity')
        class MyExpesiveEntity{
        }

        @Transaction 
        save(DTO save){
            MyExpesiveEntity entity = cache.get(dto.getID());
            if(entity == null){
                  entity = myExpesiveRespository.findById(dto.getID());
                  cache.get().put(entity.getID(),entity);
             }

             entity.setXXX(dto.getXXX()) 
             // THIS always works but Sometime when the caller is using
             // Propagation.REQUIRES_NEW. 
             // It does not work when you have nested transactions.It throws duplicated id.
             myExpesiveRespository.saveAndFlush(entity);
        }

Ответы [ 2 ]

1 голос
/ 09 мая 2020

Это специфика Hibernate c, но да, это возможно

public boolean containsEntity(EntityManager em, Class<?> entityClass, Object id) {
    SessionImplementor session = em.unwrap(SessionImplementor.class);
    EntityKey entityKey = session.generateEntityKey((Serializable) id, session.getFactory().getEntityPersister(entityClass.getName()));
    PersistenceContext pc = session.getPersistenceContext();
    return pc.getEntity(entityKey) != null || pc.getProxy(entityKey) != null;
}
1 голос
/ 09 мая 2020

Поскольку объект существует всегда, вы можете просто обновить его на основе идентификатора. См. Modifying

@Modifying
@Query("update MyExpesiveEntity expEnt set expEnt.xxxx = ?1 where expEnt.id = ?2")
void setXxxById(String xxxx, Integer id);
...