Bmis13
Bmis13

Reputation: 670

Spring JPA: How to check if Entity belongs to current JPA transaction?

I need the ability to check if Entity belongs to the current ongoing transaction. I have a JPA entity cache as a thread-local cache. Almost always when there is single @Transaction there is no issue when a same thread calls multiple times to save on service and NOT nested @Trasaction(Propagation.REQUIRES_NEW) (meaning when you have nested transactions) on same thread it does not work. Is there any way to check if JPA Entity ( MyExpesiveEntity) belongs to the current ongoing transaction?

        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);
        }

Upvotes: 0

Views: 977

Answers (2)

Christian Beikov
Christian Beikov

Reputation: 16400

It's Hibernate specific, but yes, this is possible

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;
}

Upvotes: 1

Rohit
Rohit

Reputation: 2152

Since the entity is always existing you could simply update based on the ID. See Modifying

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

Upvotes: 1

Related Questions