我正在为我的flutter expense tracker应用程序创建一个REST API。每个其他http请求都可以工作,但当我给予HTTP请求时,它会给我InvalidDataDataException ApiUsageException
用户实体:
package com.expense_tracker.expenseTracker.entities;
//imports
@Entity
@Table(name = "users")
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "uid")
private int userId;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
@Column(name = "password")
private String password;
@Column(name = "phone_number")
private String phoneNumber;
@OneToMany(mappedBy = "user",cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private List<Expenses> expenses;
// constructor,getters and setters, toString
费用主体:
package com.expense_tracker.expenseTracker.entities;
//imports
@Entity
@Table(name = "expenses")
public class Expenses {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "expense_id")
private int id;
@Column(name = "title")
private String title;
@Column(name = "amount")
private int amt;
@Column(name = "expense_date")
private String date;
@Column(name = "category")
private String category;
@ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST,
CascadeType.REFRESH })
@JoinColumn(name = "user_id")
private Users user;
// constructor,getters and setters, toString
UserDao:
package com.expense_tracker.expenseTracker.Dao.UserDao;
//imports
@Repository
public class UserDao implements UserDaoInterface {
private EntityManager entityManager;
public UserDao() {
}
@Autowired
public UserDao(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
@Transactional
public String creatUsers(Users user) {
// BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
// String password = encoder.encode(user.getPassword());
// user.setPassword(password);
// saving the user
entityManager.persist(user);
// success
return "Saved user with uid:" + user.getUserId();
}
@Override
@Transactional
public Users updateUsers(Users user) {
// updating user
return entityManager.merge(user);
}
@Override
public Users getUser(int uid) {
return entityManager.find(Users.class, uid);
}
@Override
@Transactional
public String deleteUser(int id) {
Users temp = getUser(id);
if (temp == null) {
return "Unable to find any users with uid:" + id;
}
entityManager.remove(id);
return "Removed user with uid:" + id;
}
}
ExpensesDao:
package com.expense_tracker.expenseTracker.Dao.ExpenseDao;
//imports
@Repository
public class ExpenseDao implements ExpenseDaoInterface {
private EntityManager entityManager;
@Autowired
public ExpenseDao(EntityManager entityManager) {
this.entityManager = entityManager;
}
public ExpenseDao() {
}
@Override
@Transactional
public Expenses saveExpense(Expenses expense) {
return entityManager.merge(expense);
}
@Override
public List<Expenses> getAll() {
TypedQuery<Expenses> query = entityManager.createQuery("FROM Expenses", Expenses.class);
return query.getResultList();
}
@Override
public Expenses expense(int id) {
return entityManager.find(Expenses.class, id);
}
@Override
@Transactional
public void deleteExpense(int id) {
Expenses expense = expense(id);
entityManager.remove(expense);
}
}
UserController:
package com.expense_tracker.expenseTracker.Controllers;
//imports
@RestController
@RequestMapping("/expense-tracker")
public class UserController {
private UserDao userDao;
public UserController(UserDao userDao) {
this.userDao = userDao;
}
@GetMapping("/users/{uid}")
Users getCurrentUser(@PathVariable int uid) {
return userDao.getUser(uid);
}
@PutMapping("/users")
Users updateCurrentUser(@RequestBody Users users) {
return userDao.updateUsers(users);
}
@PostMapping("/users")
String createUser(@RequestBody Users users) {
return userDao.creatUsers(users);
}
@DeleteMapping("/users/{uid}")
String deleteCurrentUser(@PathVariable int uid) {
return userDao.deleteUser(uid);
}
}
ExpensesController:
package com.expense_tracker.expenseTracker.Controllers;
//imports
@RestController
@RequestMapping("/expense-tracker")
public class ExpenseController {
private ExpenseDao expenseDao;
public ExpenseController(ExpenseDao expenseDao) {
this.expenseDao = expenseDao;
}
@GetMapping("/expense")
private List<Expenses> get() {
return expenseDao.getAll();
}
@PostMapping("/expense")
private Expenses post(@RequestBody Expenses expense) {
expense.setId(0);
return expenseDao.saveExpense(expense);
}
@GetMapping("/expense/{expenseId}")
private Expenses getSingleExpense(@PathVariable int expenseId) {
return expenseDao.expense(expenseId);
}
@PutMapping("/expense")
private Expenses update(@RequestBody Expenses expense) {
return expenseDao.saveExpense(expense);
}
@DeleteMapping("/expense/{expenseId}")
private String delete(@PathVariable int expenseId) {
Expenses temp = expenseDao.expense(expenseId);
if (temp == null) {
throw new RuntimeErrorException(null, "Expense with id" + expenseId + "not found");
}
expenseDao.deleteExpense(expenseId);
return "Succesfully deleted";
}
}
异常(发送HTTP请求后):
**发送请求的URL:(http://localhost:8080/expense-tracker/users/300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ERROR 31159 --- [nio-8080-exec-5] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.InvalidDataAccessApiUsageException: Unable to locate persister: java.lang.Integer] with root cause
org.hibernate.UnknownEntityTypeException: Unable to locate persister: java.lang.Integer
at org.hibernate.metamodel.model.domain.internal.MappingMetamodelImpl.getEntityDescriptor(MappingMetamodelImpl.java:392) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.internal.SessionImpl.getEntityPersister(SessionImpl.java:1484) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.event.internal.DefaultDeleteEventListener.deleteTransientInstance(DefaultDeleteEventListener.java:168) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.event.internal.DefaultDeleteEventListener.delete(DefaultDeleteEventListener.java:156) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:95) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:83) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:961) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.internal.SessionImpl.delete(SessionImpl.java:892) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at org.hibernate.internal.SessionImpl.remove(SessionImpl.java:2359) ~[hibernate-core-6.2.9.Final.jar:6.2.9.Final]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:360) ~[spring-orm-6.0.12.jar:6.0.12]
at jdk.proxy4/jdk.proxy4.$Proxy112.remove(Unknown Source) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:311) ~[spring-orm-6.0.12.jar:6.0.12]
at jdk.proxy4/jdk.proxy4.$Proxy112.remove(Unknown Source) ~[na:na]
at com.expense_tracker.expenseTracker.Dao.UserDao.UserDao.deleteUser(UserDao.java:58) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-6.0.12.jar:6.0.12]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.0.12.jar:6.0.12]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.0.12.jar:6.0.12]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751) ~[spring-aop-6.0.12.jar:6.0.12]
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137) ~[spring-tx-6.0.12.jar:6.0.12]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.12.jar:6.0.12]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751) ~[spring-aop-6.0.12.jar:6.0.12]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-6.0.12.jar:6.0.12]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:391) ~[spring-tx-6.0.12.jar:6.0.12]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.0.12.jar:6.0.12]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.12.jar:6.0.12]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751) ~[spring-aop-6.0.12.jar:6.0.12]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703) ~[spring-aop-6.0.12.jar:6.0.12]
at com.expense_tracker.expenseTracker.Dao.UserDao.UserDao$$SpringCGLIB$$0.deleteUser(<generated>) ~[classes/:na]
at com.expense_tracker.expenseTracker.Controllers.UserController.deleteCurrentUser(UserController.java:41) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-6.0.12.jar:6.0.12]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150) ~[spring-web-6.0.12.jar:6.0.12]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.0.12.jar:6.0.12]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.12.jar:6.0.12]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.12.jar:6.0.12]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.12.jar:6.0.12]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.12.jar:6.0.12]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.12.jar:6.0.12]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.12.jar:6.0.12]
at org.springframework.web.servlet.FrameworkServlet.doDelete(FrameworkServlet.java:936) ~[spring-webmvc-6.0.12.jar:6.0.12]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:596) ~[tomcat-embed-core-10.1.13.jar:6.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.12.jar:6.0.12]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.13.jar:6.0]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.13.jar:10.1.13]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.12.jar:6.0.12]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.12.jar:6.0.12]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.12.jar:6.0.12]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.12.jar:6.0.12]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.12.jar:6.0.12]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.12.jar:6.0.12]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1740) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.13.jar:10.1.13]
at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
数据库架构:
每个其他端点都可以工作,甚至可以删除一个费用,但是当我想删除一个用户时,它会抛出一个异常。
我是Spring Boot 的新手,我也希望你们中的一些人对我的代码有一些见解,关于我在代码中做错了什么,关于我的逻辑,等等。
最后一个问题,我应该如何保存一个特定用户的单一费用,目前我在存储费用时手动添加json中的user_id。
谢谢.
我尝试创建新的spring Boot 项目,删除DB并重新创建它,删除所有依赖项,删除JPA高级Map(一对多关系,反之亦然)。
3条答案
按热度按时间ggazkfy81#
解决方法是删除用户的费用,在删除用户之前,这是由两个实体之间的关系引起的。
有一个更好的解决方案是使用DETACH级联类型,这样Object用户和费用将被分离,并且您可以安全地删除用户,而不需要删除费用,您只需要在实体用户中更改此属性:
我希望这能帮上忙。
n53p2ov02#
正如@chris在评论中提到的,在删除用户之前必须删除费用,否则将违反约束。可以通过手动将exepense中的user of(user_id foreign key)设置为null来实现,或者在我的情况下,
entityManager.remove(id)
应该是entityManager.remove(temp)
cnjp1d6j3#
您应该调用
entityManager.remove(user);
而不是entityManager.remove(id);
实体管理器需要entity instance
而不是id
。