当前位置: 首页 > 面试题库 >

实体管理器无法在JavaFX中工作

商飞龙
2023-03-14
问题内容

我在JavaFx
fxml应用程序中都使用了数据库中的Persistence单元和Entity类,我已成功将所有表作为实体导入到Model中,问题是当我尝试插入实体时出现异常和错误,这是我的整个代码

 public class SampleController implements Initializable {
     @PersistenceContext(unitName="RawdaPU")
     private EntityManager em;

     @FXML
     private Label label;

     @FXML
     private void handleButtonAction(ActionEvent event)
     {
         Moyendidactique moyenDidactique = new Moyendidactique("1", "moyen1", "Type1");
         em.persist(moyenDidactique);
         em.close();
     }

     @Override
     public void initialize(URL url, ResourceBundle rb)
     {
         // TODO
     }     
}

这是当我按下按钮时(当handleButtonAction被触发时)我得到的全部错误。

java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1440)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:69)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:28)
    at javafx.event.Event.fireEvent(Event.java:171)
    at javafx.scene.Node.fireEvent(Node.java:6863)
    at javafx.scene.control.Button.fire(Button.java:179)
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:193)
    at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:336)
    at com.sun.javafx.scene.control.skin.SkinBase$4.handle(SkinBase.java:329)
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:64)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:217)
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:170)
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:38)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:37)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:35)
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:92)
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:53)
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:33)
    at javafx.event.Event.fireEvent(Event.java:171)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3324)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3164)
    at javafx.scene.Scene$MouseHandler.access$1900(Scene.java:3119)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1559)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2261)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:228)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:528)
    at com.sun.glass.ui.View.notifyMouse(View.java:922)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.access$100(WinApplication.java:29)
    at com.sun.glass.ui.win.WinApplication$2$1.run(WinApplication.java:67)
    at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1435)
    ... 41 more
Caused by: java.lang.NullPointerException
    at rawda.Controller.SampleController.handleButtonAction(SampleController.java:37)
    ... 46 more

我在已经存在的类似问题中找不到答案,无法确切知道我所缺少的内容,在此先感谢您的帮助。


问题答案:

为什么在代码中得到NullPointerException

该@PersistenceContext注释“表示在容器管理的EntityManager及其相关的持久化上下文的依赖。”

默认情况下,FXML控制器不是容器管理的,这意味着它们将不会设置容器管理的成员,例如标有的成员@PersistenceContext

通过为FXMLLoader
定义一个控制器工厂,可以在容器管理的环境中使用FXML控制器(例如,由于InjectionProvider用于在Afterburner.fx框架中注入值)。

但是实际上,如果您刚开始使用Java,则不需要进行注入。控件内容的反转可能会增加太多的魔力,直到您习惯了。

推荐的JavaFX集成方法供JPA初学者尝试

相反,不要依赖@PersistenceContext注释。直接从实体管理器工厂参考中获取实体管理器。有一个很好的示例,它在java2s示例“
从实体管理器创建查询”中在容器管理的环境之外使用EntityManager

在您的应用程序中,提供一种获取实体管理器的机制:

public class SampleApplication extends Application {
  static private EntityManagerFactory emf;
  static {
    try {
      emf = Persistence.createEntityManagerFactory("RawdaPU");
    } catch (Exception e) {
      System.out.println("Fatal: Unable to create entity manager factory");
      e.printStackTrace();
    }  
  }

  static public EntityManager createEntityManager() {
    return emf.createEntityManager();
  }

  @Override 
  public void start(Stage stage) {
    . . .
  }
}

在您的控制器中,从应用程序中获取一个实体管理器,并根据需要使用它。

class SampleController implements Initializable {
  @FXML
  private Label label;

  @FXML 
  private void handleButtonAction(ActionEvent event) {
    EntityManager em = SampleApplication.createEntityManager();
    Moyendidactique moyenDidactique = new Moyendidactique("1", "moyen1", "Type1");
    em.persist(moyenDidactique);
    em.close();
  }

  @Override
  public void initialize(URL location, ResourceBundle resources) {}
}

关于关闭和实体管理器的生命周期

因为您的原始示例在persist语句之后关闭了实体管理器,所以我将实体管理器的创建移到了与close方法相同的方法中,以便它们被匹配。关闭表示实体管理器无法再次使用,因此您也可以在关闭它的同一位置创建它-
这样一来,您就不会在其他地方误用它。请注意,您不需要像这样结束操作,也可以根据需要重用实体管理器,但是对于jpa入门,只需按照此示例中的说明进行操作就可以了,您可以研究更复杂的实体管理器随着您对技术有更多的经验和信心,可以重用场景。

并发问题

您还需要注意应用程序中JPA使用的并发集成。直接在按钮的动作处理程序中执行诸如JPA调用之类的操作通常不是一个好主意,因为这些调用阻塞了I /
O,这将暂停JavaFX应用程序线程并冻结应用程序UI一段时间。相反,最好利用JavaFX任务和服务并发实用程序来处理JPA交互,类似于从JavaFX
JDBC任务样本中的UI线程提取数据库工作的方式。

对于较小的本地数据库,并发可能不是什么大问题,因此您可以首先在单线程中尝试应用程序,如果工作正常,那就很好,但是如果冻结了,请查看并发实用程序。

下一步

上面的方法确实是快速入门。

了解了这种简单的方法之后,您可能需要研究一下afterburner.fx和airhacks-
control框架或(更重量级的)javafx / jpa
/ spring框架集成中展示的更结构化的设计。



 类似资料:
  • 编辑:堆栈跟踪如下: 下面是persistence.xml:

  • 我使用的是Spring BOOT应用程序,它将信息存储在数据库中。我得到错误: org.SpringFramework.transaction.CanNotCreateTransactionException:无法为事务打开JPA EntityManager 还尝试了AutoReconnect=true,在db URL中提供了端口号。

  • 我试图用JPA2.1、Hibernate和MariaDB创建基本的CRUD。 当我尝试在Tomcat上运行我的项目时,我得到以下错误: 我的数据库正在运行。我通过maven获取我的JDBC驱动程序,并且JAR存在于maven Dependencies文件夹中。下面是persistence.xml(我遵循了Pro JPA2.1教材中的示例): POM:

  • 我对EJB的概念非常陌生。我正在尝试使用实体类将前端的值插入到数据库中,但每次我这样做时,我都会收到此错误: 这是我的实体类: 我使用的是seam 2.2.1、EJB 3和Oracle 10g。 请帮助我解决此错误。

  • 问题内容: 一个很长的问题,请忍受我。 我们将Spring + JPA用于Web应用程序。我的团队在讨论如何在注入的(基于泛型的东西对AppFuse中提供的线DAO,我们不使用过的注射某种原因)。我们正在使用“应用程序管理的持久性”。 反对注入a的论点是它太重了,因此不是必需的,这就是我们需要的。而且,由于Spring将为每个Web请求创建一个DAO的新实例(我对此表示怀疑),因此不会有任何并发​

  • 在我的DAO类中,假设我有实体管理器'em'是由实体管理器工厂制作的,之后的代码如下所示:- 当我执行上面的代码行时,在堆内存中创建了一个对象,并在其中存储了其实例变量“xyz”的值。 在第3行之后,如我们所知,carEntity对象进入托管状态。它将不会转到数据库,直到我刷新或提交事务。 那么实体管理器如何知道一个实体已经进入托管状态呢?执行后,是否为CarEntity创建了一个新对象?或者它在