Search code examples
springrestnullcrudaudit

Problem with JpaRepository connection, cannot find a user by login


I have made a simple crud program.
I have used Spring audit
Everything works fine to the moment:
When I post a new "Inventory" there is no problem, but when I try to update it, I got this error
I 've got long not seen StackOverFlowError
the thing is that when I add a new object to my db, it finds user by login in repository,
with the class:

public User findUserByLogin(String login){
        return userRepository.findByLogin(login);
}
public User getThisUser(){
    return findUserByLogin(request.getUserPrincipal().getName());
}

Repository:

@Query("select u from User u where lower(u.login) = lower(?1) ")
User findByLogin(String login);

when I update object that already exists, it throws null, and trying to find something it stucks.
Did I forget about something?
I don't add the DTO's , I think that the class has no matter here. (I think :) )

@Entity
@EntityListeners({AuditingEntityListener.class})
public class Inventory extends BaseEntity{

    @Embedded
    private EntityDescription entityDescription;
    private BigDecimal price;

    public EntityDescription getEntityDescription() {
        return entityDescription;
    }

    public void setEntityDescription(EntityDescription entityDescription) {
        this.entityDescription = entityDescription;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

Base Entity:

@MappedSuperclass
public class BaseEntity extends AbstractAuditable<User, Long> {

    @Version
    private Long version;

    public Long getVersion() {
        return version;
    }

    public void setVersion(Long version) {
        this.version = version;
    }

    @Override
    public String toString() {
        return "BaseEntity{" +
                "version=" + version +
                '}';
    }
}
@Service
public class UserService {

    private final HttpServletRequest request;
    private final UserRepository userRepository;
    private final UserRoleRepository userRoleRepository;

    public UserService(HttpServletRequest request,
                       UserRepository userRepository,
                       UserRoleRepository userRoleRepository) {
        this.request = request;
        this.userRepository = userRepository;
        this.userRoleRepository = userRoleRepository;
    }

    public List<User> findAll(){
        return userRepository.findAll();
    }

    public User findUserByLogin(String login){
        return userRepository.findByLogin(login);
    }

    public User getThisUser(){
        return findUserByLogin(request.getUserPrincipal().getName());
    }
}
@GetMapping("/inventory")
    public List<InventoryDTO> allInventory(){
        return inventoryService.findAll();
    }

    @PostMapping("/inventory")
    public InventoryDTO addInventory(@RequestBody InventoryDTO inventoryDTO){
        return inventoryService.add(inventoryDTO);
    }

    @GetMapping("/inventory/{id}")
    public InventoryDTO getInventoryById(@PathVariable Long id){
        return inventoryService.findById(id);
    }

    @DeleteMapping("/inventory/{id}")
    public List<InventoryDTO> deleteItem(@PathVariable Long id){
        inventoryService.remove(id);
        return inventoryService.findAll();
    }

    @PostMapping("/inventory/{id}")
    public InventoryDTO updateInventory(@PathVariable Long id, @RequestBody InventoryDTO inventoryDTO){
        return inventoryService.update(id, inventoryDTO);
    }
}

And the error:

    java.lang.StackOverflowError: null
    at java.base/java.net.URL.<init>(URL.java:605) ~[na:na]
    at java.base/java.net.URL.<init>(URL.java:553) ~[na:na]
    at java.base/jdk.internal.loader.URLClassPath$FileLoader.getResource(URLClassPath.java:1222) ~[na:na]
    at java.base/jdk.internal.loader.URLClassPath.getResource(URLClassPath.java:317) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:718) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:644) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
    at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016) ~[na:na]
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:823) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:721) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:644) ~[na:na]
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:602) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na]
    at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1533) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.query.internal.AbstractProducedQuery.getSingleResult(AbstractProducedQuery.java:1581) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution$SingleEntityExecution.doExecute(JpaQueryExecution.java:196) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.data.jpa.repository.query.JpaQueryExecution.execute(JpaQueryExecution.java:88) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:154) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.data.jpa.repository.query.AbstractJpaQuery.execute(AbstractJpaQuery.java:142) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor$QueryMethodInvoker.invoke(QueryExecutorMethodInterceptor.java:195) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.doInvoke(QueryExecutorMethodInterceptor.java:152) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.data.repository.core.support.QueryExecutorMethodInterceptor.invoke(QueryExecutorMethodInterceptor.java:130) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:80) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:367) ~[spring-tx-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:118) ~[spring-tx-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139) ~[spring-tx-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:149) ~[spring-data-jpa-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at com.sun.proxy.$Proxy102.findByLogin(Unknown Source) ~[na:na]
    at com.teamcompetencymatrix.www.service.UserService.findUserByLogin(UserService.java:31) ~[classes/:na]
    at com.teamcompetencymatrix.www.service.UserService.getThisUser(UserService.java:35) ~[classes/:na]
    at com.teamcompetencymatrix.www.config.AuditorAwareImpl.getCurrentAuditor(AuditorAwareImpl.java:24) ~[classes/:na]
    at org.springframework.data.auditing.AuditingHandler.lambda$touchAuditor$6(AuditingHandler.java:193) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at java.base/java.util.Optional.map(Optional.java:258) ~[na:na]
    at org.springframework.data.auditing.AuditingHandler.touchAuditor(AuditingHandler.java:191) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.data.auditing.AuditingHandler.lambda$touch$0(AuditingHandler.java:165) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at java.base/java.util.Optional.map(Optional.java:258) ~[na:na]

Solution

  • The solution was in UserRepository

    I have added a @Transactional annotation

    The problem was with finding an auditor. It was a problem with transactions, so making a new one solved the problem.

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Query("select u from User u where lower(u.login) = lower(?1) ")
    User findAuditorByLogin(String login);
    

    This is a working solution, but maybe there are better.