实体管理器不工作的JavaFX(Entity Manager not working in Java

2019-09-02 14:10发布

我使用的持久性单元和实体类的数据库,都在一个JavaFX应用FXML,我成功导入我的表,因为在我的模型实体的proble是,我得到一个异常和错误,当我尝试插入一个实体,这里是我的全部代码

 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

我找不到在已经存在类似的问题的答案,不能知道我错过什么,谢谢您帮助。

Answer 1:

为什么你在你的代码得到一个NullPointerException

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

默认情况下FXML控制器不是容器管理,这意味着它们不打算设置容器管理构件诸如那些标有@PersistenceContext

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

不过说真的,你不需要做注射,如果你是刚刚开始使用Java。 该控制的东西反转可能增加了一个有点太多魔力,直到你习惯了。

推荐JavaFX的集成方法来尝试使用JPA初学者

取而代之的是,不依靠@PersistenceContext注解。 直接从实体管理器工厂引用获取的实体管理器。 有使用容器管理的环境之外提供一个EntityManager的java2s样品中的一个很好的例子创建查询从实体管理器 。

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

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) {}
}

在关闭和实体管理器生存期

因为你原来的例子关闭实体管理器的持久语句后,我搬到了实体管理器创建成同样的方法,close方法使它们是匹配的。 密切意味着实体管理器无法再次使用,所以你不妨在您关闭它在同一个地方创建它 - 这样,你不能错误地重用它在其他地方。 请注意,您不需要做亲密这样的,如果你喜欢可以重用实体管理器,但对于入门JPA,只是做它作为在这个例子中答案很可能很好,你可以看看更复杂的实体管理器重复使用的情况,你获得更多的经验,并与技术的信心。

并发关注

您还需要了解在应用程序中使用JPA的并发集成。 做的东西,如JPA按钮的操作处理程序直接调用通常不是因为呼叫阻塞I / O,甚至停止了JavaFX应用程序线程和冻结您的应用程序UI特定的时间内一个伟大的想法。 相反,它是最好利用的JavaFX的任务和服务的并发工具来处理类似数据库如何工作从UI线程中的抽象JPA互动的JavaFX JDBC任务样本 。

对于一个小的本地数据库是并发性可能不是太大的关注,所以你可以尝试你的应用程序第一单线程的,如果它工作得很好,很棒,但如果是凝固起来再看看进入并发工具。

下一步

上述方法真的是一个快速入门的事情。

一旦你明白这个简单的方法,你可能想看看在展示了更加结构化设计afterburner.fx和airhacks控制框架或(更重量级) 的JavaFX / JPA / Spring框架的集成 。



文章来源: Entity Manager not working in JavaFX