Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NoResultException is not wrapped into EmptyResultDataAccessException #33088

Closed
trueMiskin opened this issue Jun 23, 2024 · 7 comments
Closed
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: feedback-provided Feedback has been provided status: invalid An issue that we don't feel is valid

Comments

@trueMiskin
Copy link

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.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jun 23, 2024
@quaff
Copy link
Contributor

quaff commented Jun 24, 2024

It's a feature not bug.

@jhoeller
Copy link
Contributor

jhoeller commented Jun 24, 2024

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.

@jhoeller jhoeller added status: waiting-for-feedback We need additional information before we can continue in: data Issues in data modules (jdbc, orm, oxm, tx) labels Jun 24, 2024
@trueMiskin
Copy link
Author

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" />

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jun 24, 2024
@jhoeller
Copy link
Contributor

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...

@trueMiskin
Copy link
Author

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.

@jhoeller
Copy link
Contributor

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.

@jhoeller
Copy link
Contributor

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

@jhoeller jhoeller closed this as not planned Won't fix, can't repro, duplicate, stale Jun 24, 2024
@jhoeller jhoeller added status: invalid An issue that we don't feel is valid and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jun 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: data Issues in data modules (jdbc, orm, oxm, tx) status: feedback-provided Feedback has been provided status: invalid An issue that we don't feel is valid
Projects
None yet
Development

No branches or pull requests

4 participants