Проект Spring-Data не получает мой Get / Post Объект не найден для запроса

#java #spring #spring-boot #hibernate #spring-mvc

#java #весна #spring-boot #спящий режим #spring-mvc

Вопрос:

Я закончил создание простого проекта Spring-boot, в который я могу вводить пользователей, и с помощью команды Get он возвращает мне имя (из списка идентичных имен) с самой старой датой ввода. К сожалению, каждый раз, когда я запрашиваю Get, он возвращает эту ОШИБКУ:

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

В терминале весенней загрузки у меня эта ОШИБКА:

 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 нет проблем, так как все зависимости верны.

Комментарии:

1. Я бы попросил использовать postman или другой инструмент для тестирования вместо curl, и в соответствии с вашей ошибкой в классе обслуживания в CriteriaBuilder идентификатор пользователя не найден. похоже, проблема в диспетчере сущностей. вы могли бы найти точную проблему, но правильный код dubug или TDD. Другой вариант — использовать CrudRepository или JpaRepository

2. Вы неправильно используете spring data jpa. Вы должны использовать JpaRepository . Также я вижу, что вы используете @PathVariable запрос POST для отправки нескольких пользовательских полей в URL. Почему вы не используете @RequestBody

3. Привет, Аджит! вы правы, на самом деле лучше использовать @RequestParam

Ответ №1:

Ваш create метод недействителен. И из-за этого вы фактически не можете получить некоторые данные. Вы только вызвали persist метод, но вам также нужно позвонить flush , чтобы фактически записать это в БД. Фрагмент кода может выглядеть следующим образом:

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

Комментарии:

1. Привет, Evg! не были бы вы достаточно любезны, чтобы показать мне, куда поместить этот фрагмент кода??

2. Конечно, он должен быть помещен внутри вашего public void create(UserEntity entity) метода в вашем UserRepositoryImpl классе. ps. Просто обновил ответ.

3. Когда я использую ваш метод, я выхожу из этой ошибки: .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

4. Хорошо, я снова обновлю ответ, проверьте его. Смысл здесь в том, чтобы делегировать обработку транзакций Spring вместо ручной обработки.

5. Даже вставка изменения ничего не меняет

Ответ №2:

Ну, вы не получаете результата в своем запросе, но принудительно выполняете getSingleResult() его. Вы можете использовать CrudRepository из Spring, это немного проще.

Комментарии:

1. Привет, Милго! Большое вам спасибо за ваш ответ, к сожалению, я не могу использовать Crud для различных требований, которые были наложены на меня