jpa InvalidDataAccessApiUsageException:(“无法找到persister:在Sping Boot 中对Http请求执行“java.lang. java”)

llmtgqce  于 2023-10-19  发布在  Java
关注(0)|答案(3)|浏览(106)

我正在为我的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(一对多关系,反之亦然)。

ggazkfy8

ggazkfy81#

解决方法是删除用户的费用,在删除用户之前,这是由两个实体之间的关系引起的。
有一个更好的解决方案是使用DETACH级联类型,这样Object用户和费用将被分离,并且您可以安全地删除用户,而不需要删除费用,您只需要在实体用户中更改此属性:

@OneToMany(mappedBy = "user", cascade = CascadeType.DETACH, fetch = FetchType.EAGER)private List<Expenses> expenses;

我希望这能帮上忙。

n53p2ov0

n53p2ov02#

正如@chris在评论中提到的,在删除用户之前必须删除费用,否则将违反约束。可以通过手动将exepense中的user of(user_id foreign key)设置为null来实现,或者在我的情况下,entityManager.remove(id)应该是entityManager.remove(temp)

cnjp1d6j

cnjp1d6j3#

您应该调用entityManager.remove(user);而不是entityManager.remove(id);实体管理器需要entity instance而不是id

相关问题