We upgraded spring from v4 to 6.0.22 and Hibernate from v4 to 6.4.9 and we spotted that jakarta.persistence.NoResultException is not wrapped into EmptyResultDataAccessException. This seems to be a bug.

Comment From: quaff

It's a feature not bug.

Comment From: jhoeller

Where specifically is it not getting wrapped? We generally do wrap NoResultException in EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible. Are you possibly invoking an EntityManager directly in which case you will get the raw JPA exceptions by design? You may register a PersistenceExceptionTranslationPostProcessor then but this will only affect the proxy callers of your service/repository beans, not the immediate ´EntityManager` operations either.

Comment From: trueMiskin

Yes, we invoke EntityManager methods. Normal service looks like this:

@Service
public class ServiceName implements IServiceName {

    @PersistenceContext
    EntityManager em;

    @Transactional(readOnly = true)
    @Override
    public List<ISomeObject> findSomething(IParamObject param) {
        Query q = em.createNamedQuery("QueryName");
        q.setParameter("param", param);

        return q.getResultList();
    }
}

In spring 4, exceptions were wrapped even when calling EntityManager methods. Has anything changed since then? I have not seen any note on that in the migration guides.

By registering the PersistenceExceptionTranslationPostProcessor will exceptions be wrapped by spring? Is registering done by adding these lines to the config?

<bean id="persistenceExceptionTranslationPostProcessor"
   class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

Comment From: jhoeller

Generally, such a PersistenceExceptionTranslationPostProcessor is necessary indeed, automatically applying exception translation to all @Repository beans. You could also apply it to your @Service classes through declaring the repositoryAnnotationType property on PersistenceExceptionTranslationPostProcessor accordingly, setting it to org.springframework.stereotype.Service.

Not sure why this happened automatically for you with Spring 4. JdbcTemplate and co perform it automatically within the delegate itself but we never really had such automatic translation for a plain JPA EntityManager...

Comment From: trueMiskin

I added this:

<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor">
        <property name="repositoryAnnotationType" value="org.springframework.stereotype.Service" />   
    </bean>

to config file but errors show up:

Bean with name 'serviceName' has been injected into other beans [serviceName2] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.

I don't get why this change raises this error. Maybe a good solution is to use raw JPA exceptions.

Comment From: jhoeller

It looks like there is a circular reference between two of your services: In such a case, proxying might happen too late which is what that exception message says. Breaking a circular reference through a lazy reference is usually straightforward, so that e.g. "serviceName2" would use an @Lazy Service serviceName declaration or ObjectFactory<Service> serviceName if you'd like to avoid annotations.

Comment From: jhoeller

Since the framework bits seem to work as intended here, I'm closing this issue.