Search code examples
javaspringjpaopenjpa

Persisting inside the Spring service results into TransactionRequiredException


For some reason persisting inside the Spring service results into TransactionRequiredException

I am not sure how much information I should include for this problem, so I can add info if needed. I have a Spring service which extends the Abstract class for transaction management.

If I do save inside my method I am getting org.apache.renamed.openjpa.persistence.TransactionRequiredException

even if I specify @Transactional for the method.

The same method called by invoking the service outside of the Service class works fine.

My method:

@Service("PriceListLookupService")
public class PriceListLookupServiceImpl extends
    AbstractEpEntityService<PriceList> implements
    PriceListLookupService {
@Override
@Transactional
public PriceList createPriceListForCatalogStore(String catalogName,
        String storeName) {
    // Catalog catalog = catalogService.findByName(catalogName);
    try {
        PriceList priceList = new PriceList();
        this.saveOrUpdate(priceList);
    } catch (Exception e) {
        LOG.error("createDestinationPriceListError", e);
    }
    return null;
}

Abstract class

public abstract class AbstractEntityService<T, I> implements EntityService<T, I> {

@PersistenceContext
protected EntityManager entityManager;
protected Class<T> entityClass;


@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
public T saveOrUpdate(T entity) {
    if(isEntityPersistent(entity)) {
        entity = entityManager.merge(entity);
    } else {
        entityManager.persist(entity);
    }
    entityManager.flush();
    return entity;
}

The exception:

org.apache.renamed.openjpa.persistence.TransactionRequiredException: To perform this operation, it must be written within a transaction, or your settings must allow nontransactional writes and must not detach all nontransactional reads.


Solution

  • It appeared, that the 1st called method in a service should have the @Transactional annotation. So, if one calls first method A, which calls method B inside a service, then the method A must have the @Transactional annotation.