英文:
Spring-Data Mysql cannot find the name in the DB
问题
我对Spring-Data MySQL还不太熟悉,我创建了一个小方法,让它从一个名字列表中返回一个名称,它会返回具有最旧的记录日期的名称。不幸的是,当我执行获取操作时,它返回给我这个:
D:>curl -G localhost:8080/demo/first -d name=Biagio
{"timestamp":"2020-10-02T09:29:33.704+00:00","status":404,"error":"Not Found","message"
我已经尝试了各种方法,但到目前为止都没有成功。以下是该方法和相关控制器。
UserRepositoryImpl.java
```java
package com.example.accessingdatamysql;
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;
@Component
public class UserRepositoryImpl implements UserRepository {
private final EntityManager em;
public UserRepositoryImpl(EntityManager entityManager) {
this.em = entityManager;
}
@Override
public User findFirstByName(String name) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.select(root).where(builder.equal(root.get("name"), name));
criteria.orderBy(builder.asc(root.get("timestamp")));
TypedQuery<User> query = em.createQuery(criteria).setMaxResults(1);
return query.getSingleResult();
}
@Override
public void create(User entity) {
em.persist(entity);
}
}
MainController.java
package com.example.accessingdatamysql;
import javax.persistence.NoResultException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(path="/demo")
public class MainController {
@Autowired
private UserRepository userRepository;
@Transactional
@PostMapping(path="/add")
public @ResponseBody String addNewUser (@RequestParam String name, @RequestParam String email, @RequestParam String surname) {
User n = new User();
n.setName(name);
n.setSurname(surname);
n.setEmail(email);
userRepository.create(n);
return "Saved";
}
@GetMapping("/first")
User one(@RequestParam String name) {
System.out.print(name);
try {
return userRepository.findFirstByName(name);
} catch (NoResultException nre) {
return null;
}
}
}
还有User和UserRepository.java
User.java
package com.example.accessingdatamysql;
import java.sql.Timestamp;
import java.time.Instant;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
public String name;
private String email;
private String surname;
@Column(name="stmp", columnDefinition = "TIMESTAMP (6)")
Timestamp timestamp = Timestamp.from(Instant.now());
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
public Timestamp getTimestamp() {
return timestamp;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
UserRepository.java
package com.example.accessingdatamysql;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository {
User findFirstByName(String name);
void create(User entity);
}
英文:
I'm new to Spring-Data Mysql, I created a little method to make it give me a name from a list of names, it returns me the name with the oldest entry date. Unfortunately when I do the get it returns me this :
D:\>curl -G localhost:8080/demo/first -d name=Biagio
{"timestamp":"2020-10-02T09:29:33.704+00:00","status":404,"error":"Not Found","message
I've tried them all a little but so far I can't be successful. Below is the method and the relative controller
UserRepositoryImpl.java
package com.example.accessingdatamysql;
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;
@Component
public class UserRepositoryImpl implements UserRepository {
private final EntityManager em;
public UserRepositoryImpl(EntityManager entityManager) {
this.em = entityManager;
}
@Override
public User findFirstByName(String name) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<User> criteria = builder.createQuery(User.class);
Root<User> root = criteria.from(User.class);
criteria.select(root).where(builder.equal(root.get("name"), name));
criteria.orderBy(builder.asc(root.get("timestamp")));
TypedQuery<User> query = em.createQuery(criteria).setMaxResults(1);
return query.getSingleResult();
}
@Override
// per la creazione//
public void create(User entity) {
em.persist(entity);
}
}
mainController.java
package com.example.accessingdatamysql;
import javax.persistence.NoResultException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping(path="/demo")
public class MainController {
@Autowired
private UserRepository userRepository;
@Transactional
@PostMapping(path="/add")
public @ResponseBody String addNewUser (@RequestParam String name
, @RequestParam String email,@RequestParam String surname)
{
User n = new User();
n.setName(name);
n.setSurname(surname);
n.setEmail(email);
userRepository.create(n);
return "Saved";
}
@GetMapping("/first")
User one(@RequestParam String name) {
System.out.print(name);
try { return userRepository.findFirstByName(name);
} catch (NoResultException nre) {
return null; }
}
}
I add User and UserRepository.java for everything
User.java
package com.example.accessingdatamysql;
import java.sql.Timestamp;
import java.time.Instant;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id;
public String name;
private String email;
private String surname;
@Column(name="stmp", columnDefinition = "TIMESTAMP (6)")
Timestamp timestamp = Timestamp.from(Instant.now());
public void setTimestamp(Timestamp timestamp) {
this.timestamp = timestamp;
}
public Timestamp getTimestamp() {
return timestamp;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
UserRepository.java
package com.example.accessingdatamysql;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository {
User findFirstByName(String name);
void create(User entity);
}
EDIT: I insert the database referenced by this small project:
+----+---------------------+--------+----------------------------+---------+
| id | email | name | stmp | surname |
+----+---------------------+--------+----------------------------+---------+
| 32 | mirketto90@yahoo.it | Mirko | 2020-10-01 12:31:47.827000 | NULL |
| 36 | biagio@gmail.com | Biagio | 2020-10-01 16:31:31.687000 | Vaso |
| 37 | biagio@gmail.com | Biagio | 2020-10-01 16:31:50.077000 | Vaso |
| 38 | biagio@gmail.com | Biagio | 2020-10-01 18:35:45.992000 | Vaso |
+----+---------------------+--------+----------------------------+---------+
答案1
得分: 1
我看到的第一件事如下:
- 你的
/demo/first
方法不是公开的。 - 调用此端点的正确方法应为
curl localhost:8080/demo/first?name=Biagio -H "Accept: application/json"
。
英文:
the first things I see are the following:
- Your method for
/demo/first
is not public. - The proper way to call this endpoint should be
curl localhost:8080/demo/first?name=Biagio -H "Accept: application/json"
答案2
得分: 0
你应该能够通过浏览器验证端点 localhost:8080/demo/first?name=Biagio
,因为它默认提交 GET 请求。
我成功复现了这个问题,你应该移除类级别的映射,并在 MainController
的方法中提供完整路径:
@RestController
public class MainController {
@Autowired
private UserRepository userRepository;
@Transactional
@PostMapping("/demo/add")
public @ResponseBody String addNewUser (
@RequestParam String name,
@RequestParam String email,
@RequestParam String surname)
{
User n = new User();
n.setName(name);
n.setSurname(surname);
n.setEmail(email);
userRepository.create(n);
return "Saved";
}
@GetMapping("/demo/first")
public User one(@RequestParam String name) {
System.out.print(name);
return userRepository.findFirstByName(name);
}
}
以下 curl
请求应该成功:
curl -X GET localhost:8080/demo/first?name=Biagio
curl -G localhost:8080/demo/first?name=Biagio
curl -G localhost:8080/demo/first -d name=Biagio
更新:
以下修复方法在方法级别的映射中也可以正常工作,无需在映射前添加斜杠:
@Controller
@RequestMapping("/demo") // 尾部斜杠可选,也可以是 "/demo/"
public class MainController {
@Autowired
private UserRepository userRepository;
@Transactional
@PostMapping("add") // 无前导斜杠
public @ResponseBody String addNewUser (/* ... */) {
// ...
}
@GetMapping("first") // 无前导斜杠
public User one(@RequestParam String name) {
return userRepository.findFirstByName(name);
}
}
英文:
You should be able to verify the endpoint localhost:8080/demo/first?name=Biagio
using your browser, as it submits GET requests by default.
I managed to reproduce this issue, you should remove the class-level mapping and provide full path on the method in MainController
:
@RestController
public class MainController {
@Autowired
private UserRepository userRepository;
@Transactional
@PostMapping("/demo/add")
public @ResponseBody String addNewUser (
@RequestParam String name,
@RequestParam String email,
@RequestParam String surname)
{
User n = new User();
n.setName(name);
n.setSurname(surname);
n.setEmail(email);
userRepository.create(n);
return "Saved";
}
@GetMapping("/demo/first")
public User one(@RequestParam String name) {
System.out.print(name);
return userRepository.findFirstByName(name);
}
}
The following curl
requests should succeed:
curl -X GET localhost:8080/demo/first?name=Biagio
curl -G localhost:8080/demo/first?name=Biagio
curl -G localhost:8080/demo/first -d name=Biagio
Update<br/>
The following fix is also working without leading slashes in the method-level mappings:
@Controller
@RequestMapping("/demo") // trailing slash optional, could be "/demo/"
public class MainController {
@Autowired
private UserRepository userRepository;
@Transactional
@PostMapping("add") // no leading slash
public @ResponseBody String addNewUser (/* ... */) {
// ...
}
@GetMapping("first") // no leading slash
public User one(@RequestParam String name) {
return userRepository.findFirstByName(name);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论