Using @Autowired Spring service in Hibernate UserType instance

276 Views Asked by At

What I am trying to do is to use autowired Spring Service in my UserType. The problem is (as I believe) that Hibernate uses AuthorType.INSTANCE, and it's constructed with no parameters, meaning that field BookShelfService is null.

Is there any way to fix it?

PersonType (extends CommonType which implements UserType):

@Component
public class PersonType extends CommonType {
    public static final PersonType INSTANCE = new PersonType();
    private BookShelfService shelfService;

    @Autowired
    public void setShelfService(BookShelfService shelfService) {
        this.shelfService = shelfService;
        System.out.println("BSS is SET in "+ this);
    }

    public PersonType() {
        super(Person.class);
        System.out.println("PT instd: "+this);
    }

    @Override
    public int[] sqlTypes() {
        return new int[] {LongType.INSTANCE.sqlType()};
    }

    @Override
    public Object nullSafeGet(ResultSet resultSet,
                              String[] strings,
                              SharedSessionContractImplementor sharedSessionContractImplementor,
                              Object o) throws HibernateException, SQLException {
        long id = Long.parseLong(resultSet.getString(strings[0]));
        System.out.println("BSS in " + this + ": "+shelfService);
        Optional<Person> person = shelfService.findPersonById(id); ** NullPointerException HERE **

        if (person.isPresent()) {
            return person;
        } else throw new IllegalArgumentException("SEVERE: No Person found with id: "+id);
    }

    @Override
    public void nullSafeSet(PreparedStatement preparedStatement,
                            Object o, int i,
                            SharedSessionContractImplementor sharedSessionContractImplementor) throws HibernateException, SQLException {
        if (o == null) {
            preparedStatement.setNull(i, LongType.INSTANCE.sqlType());
        } else {
            preparedStatement.setLong(i, ((Person) o).getId());
        }
    }
}

BookShelfService:

@Service
public class BookShelfService {
    private BooksRepository booksRepository;
    private AuthorsRepository authorsRepository;
    private BookOwnersRepository bookOwnersRepository;
    private PeopleRepository peopleRepository;

    @Autowired
    public BookShelfService(BooksRepository booksRepository,
                            AuthorsRepository authorsRepository,
                            BookOwnersRepository bookOwnersRepository,
                            PeopleRepository peopleRepository) {
        this.booksRepository = booksRepository;
        this.authorsRepository = authorsRepository;
        this.bookOwnersRepository = bookOwnersRepository;
        this.peopleRepository = peopleRepository;
    }

    public BookShelfService() {
    }

    public List<Book> findBooksByAuthorNameAndSurname(String name, String surname) {
        Optional<Person> person = peopleRepository.findPersonByNameAndSurname(name, surname);

        if (!person.isPresent())
            throw new IllegalArgumentException("No Person found with name: " + name + ", surname: " + surname);

        Optional<Author> author = authorsRepository.findAuthorByPerson(person.get());

        if (!author.isPresent())
            throw new IllegalArgumentException("No Author found with name: " + name + ", surname: " + surname);

        return booksRepository.findBooksByAuthor(author.get());
    }
        // *** etc.
}

Error:

Exception in thread "main" java.lang.NullPointerException
    at bookshelf.jpa.type.PersonType.nullSafeGet(PersonType.java:47)
    at org.hibernate.type.CustomType.nullSafeGet(CustomType.java:119)
    at org.hibernate.type.AbstractType.hydrate(AbstractType.java:91)
    at org.hibernate.persister.entity.AbstractEntityPersister.hydrate(AbstractEntityPersister.java:3041)
    at org.hibernate.loader.Loader.loadFromResultSet(Loader.java:1866)
    at org.hibernate.loader.Loader.hydrateEntityState(Loader.java:1794)
    at org.hibernate.loader.Loader.instanceNotYetLoaded(Loader.java:1767)
    at org.hibernate.loader.Loader.getRow(Loader.java:1615)
    at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:745)
    at org.hibernate.loader.Loader.processResultSet(Loader.java:1008)
    at org.hibernate.loader.Loader.doQuery(Loader.java:964)
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:354)
    at org.hibernate.loader.Loader.doList(Loader.java:2815)
    at org.hibernate.loader.Loader.doList(Loader.java:2797)
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2629)
    at org.hibernate.loader.Loader.list(Loader.java:2624)
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506)
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:396)
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1396)
    at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1558)
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1526)
    at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1574)
    at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.getSingleResult(CriteriaQueryTypeQueryAdapter.java:111)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$DeferredQueryInvocationHandler.invoke(SharedEntityManagerCreator.java:409)
    at com.sun.proxy.$Proxy83.getSingleResult(Unknown Source)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:196)
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154)
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:618)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:605)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
    at com.sun.proxy.$Proxy76.findAuthorByPerson(Unknown Source)
    at bookshelf.jpa.service.BookShelfService.findBooksByAuthorNameAndSurname(BookShelfService.java:62)
    at bookshelf.Application.findBlochBooks(Application.java:53)
    at bookshelf.Application.main(Application.java:48)

By the way, I noticed that AuthorType gets instantiated in my case 18 times and the 6th in the output list is always the one that is used and produces NullPointerException.

0

There are 0 best solutions below