【问题标题】:Spring-Data Project is not receiving my Get/Post No entity found for querySpring-Data 项目没有收到我的 Get/Post No entity found for query
【发布时间】:2020-10-05 08:58:24
【问题描述】:

我完成了一个简单的 Spring-boot 项目的创建,我可以在其中输入用户,并通过 Get 命令返回具有最早输入日期的名称(来自相同名称的列表)。不幸的是,每次我要求 Get 它都会返回这个 ERROR

D:\>curl -G localhost:8080/demo/first -d name=Biagio
{"timestamp":"2020-10-05T08:52:34.741+00:00","status":500,"error":"Internal Server Error","message":"","path":"/demo/first"}

在 Spring-Boot 终端我有这个 ERROR

Biagio
2020-10-05 10:52:34.722 ERROR 8860 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.EmptyResultDataAccessException: No entity found for query; nested exception is javax.persistence.NoResultException: No entity found for query] with root cause

即使我尝试发布/添加,我也会收到一条消息,它已保存在数据库中,但实际上并没有保存任何内容

下面我添加所有相关方:

AccessingDataMysqlApplication.java

package com.example.accessingdatamysql;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.ComponentScan;


@SpringBootApplication
public class AccessingDataMysqlApplication {

  public static void main(String[] args) {
    SpringApplication.run(AccessingDataMysqlApplication.class, args);
  }

}

MainController.java

package com.example.accessingdatamysql.rest;

import javax.persistence.NoResultException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.service.UserService;

@RestController
@RequestMapping("/demo")
public class MainController {

@Autowired
private UserService userService;

@Transactional
//@RequestMapping(value = "/add/", method = RequestMethod.POST)
@PostMapping(path="/demo/add")
public String addNewUser(@PathVariable("name") String name, @PathVariable("email") String email,
@PathVariable("surname") String surname) {

UserDto n = new UserDto();
n.setName(name);
n.setSurname(surname);
n.setEmail(email);
userService.create(n);
return "User Saved in DB";
}

@SuppressWarnings({ "rawtypes", "unchecked" })
//@RequestMapping(value = "/fetchUser/{name}", method = RequestMethod.GET)
@GetMapping("/demo/first")
public ResponseEntity<UserDto> fetchUser(@PathVariable("name") String name) {
System.out.println(name);

try {
UserDto namefound = userService.findFirstByName(name);
System.out.println("Name found");
ResponseEntity<UserDto> user = new ResponseEntity<UserDto>(namefound, HttpStatus.OK);
return user;
} catch(NoResultException ne) {
System.out.println("User not found");
return new ResponseEntity("User not found with name : " + name, HttpStatus.NOT_FOUND);
}

}
}

UserService.java

package com.example.accessingdatamysql.service;

import org.springframework.stereotype.Service;

import com.example.accessingdatamysql.model.UserDto;
@Service
public interface UserService {

    UserDto findFirstByName(String name);
    
    void create(UserDto user);
        
}

UserServiceImpl.java

package com.example.accessingdatamysql.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.model.UserEntity;
import com.example.accessingdatamysql.repo.UserRepository;
import com.example.accessingdatamysql.util.UserMapper;

@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserRepository userRepository;

    @Autowired
    UserMapper mapper;

    @Override
    public UserDto findFirstByName(String name) {
        UserEntity entity = userRepository.findFirstByName(name);
        return mapper.toDtoMapper(entity);
    }

    @Override
    public void create(UserDto user) {
        UserEntity entity = mapper.toEntityMapper(user);
        userRepository.create(entity);
    }

}

UserMapper.java

package com.example.accessingdatamysql.util;

import org.mapstruct.Mapper;

import com.example.accessingdatamysql.model.UserDto;
import com.example.accessingdatamysql.model.UserEntity;



@Mapper(componentModel = "spring")
public interface UserMapper {   
    
    public UserEntity toEntityMapper (UserDto user);    
    public UserDto toDtoMapper (UserEntity userEntity);
    
}

UserRepository.java

package com.example.accessingdatamysql.repo;


import org.springframework.stereotype.Repository;

import com.example.accessingdatamysql.model.UserEntity;


@Repository
public interface UserRepository {
    UserEntity findFirstByName(String name);
    void create(UserEntity entity);
    
}

UserRepositoryImpl.java

package com.example.accessingdatamysql.service;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.springframework.stereotype.Component;

import com.example.accessingdatamysql.model.UserEntity;
import com.example.accessingdatamysql.repo.UserRepository;

@Component
public class UserRepositoryImpl implements UserRepository {

    private final EntityManager em;

    public UserRepositoryImpl(EntityManager entityManager) {
        this.em = entityManager;
    }

    @Override
    public UserEntity findFirstByName(String name) {
        CriteriaBuilder builder = em.getCriteriaBuilder();
        CriteriaQuery<UserEntity> criteria = builder.createQuery(UserEntity.class);
        Root<UserEntity> root = criteria.from(UserEntity.class);
        criteria.select(root).where(builder.equal(root.get("name"), name));
        criteria.orderBy(builder.asc(root.get("timestamp")));
        TypedQuery<UserEntity> query = em.createQuery(criteria).setMaxResults(1);
        return query.getSingleResult();

    }

    @Override
//  per la creazione//
    public void create(UserEntity entity) {
        em.persist(entity);
    }

}

UserDto.java

package com.example.accessingdatamysql.model;

import java.io.Serializable;
import java.sql.Timestamp;

public class UserDto implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -7621330660870602403L;
    /**
     * 
     */

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Timestamp getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Timestamp timestamp) {
        this.timestamp = timestamp;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    private Timestamp timestamp;
    private String email;
    private String surname;

}

如果你还需要我可以提供 User.java 和 pom 文件,但是 pom 没有问题,因为依赖关系都是正确的。

【问题讨论】:

  • 我会要求使用邮递员或其他工具代替 curl 进行测试,并且根据您在 CriteriaBuilder 中服务类的错误,找不到 UserEntity。实体管理器似乎有问题。你可以找到确切的问题,但正确的 dubug 或 TDD 代码。其他选项是使用 CrudRepository 或 JpaRepository
  • 您没有正确使用 spring data jpa。你应该使用JpaRepository。我还看到您在 POST 请求中使用 @PathVariable 在 URL 中发送多个用户字段。为什么不使用@RequestBody
  • 嗨阿吉特!你说得对,实际上最好使用@RequestParam

标签: java spring spring-boot hibernate spring-mvc


【解决方案1】:

您的create 方法无效。因此,您实际上无法检索某些数据。 您只调用了persist 方法,但您还需要调用flush 才能将其实际写入数据库。代码 sn-p 可能如下所示:

@Transactional
@Override
public void create(UserEntity entity) {        
    if (!em.contains(entity)) {
        em.persist(entity);
        em.flush();
    }
}

【讨论】:

  • 嗨,Evg!你能告诉我把这段代码放在哪里吗??
  • 当然,它应该放在 UserRepositoryImpl 类中的 public void create(UserEntity entity) 方法中。 p.s.刚刚更新了答案。
  • 当我使用你的方法时,我摆脱了这个错误:.InvalidDataAccessApiUsageException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead; nested exception is java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead] with root cause java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT instead
  • 好的,那我再更新一下答案,看看吧。这里的重点是将事务处理委托给 Spring 而不是手动处理。
  • 即使插入更改也不会改变任何内容
【解决方案2】:

好吧,您的查询没有结果,但使用getSingleResult() 强制返回。您可以使用 Spring 中的 CrudRepository,这样会更容易一些。

【讨论】:

  • 嗨,米尔戈!非常感谢您的回复,很遗憾我无法使用 Crud 来满足对我施加的各种要求
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-02
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
  • 2012-08-09
相关资源
最近更新 更多