Настольное приложение JavaFX — с использованием HSQLDB (встроенного) и гибернации

#java #hibernate #javafx #hsqldb

#java #гибернация #javafx #hsqldb

Вопрос:

Есть ли хороший учебник по использованию HSQLDB, Hibernate и JavaFX. Я использую eclipse в качестве своей среды разработки. В моей модели проекта переменные определены следующим образом:

  @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 @Column(name = "PROJECTID")
 private long projectId;

 @Column(name = "PROJECTNAME")
 private final StringProperty projectName;

 @Column(name = "PROJECTJIBP")
 private final StringProperty projectJIBP;
 

Является ли это допустимым способом использования гибернации с JavaFX?

persistance.xml является:

     <?xml version="1.0" encoding="UTF-8"?>

<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
  version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="test" transaction-type="RESOURCE_LOCAL">
    <class> handwrittencode.eiar.model.Project</class>
    <properties>
      <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver" />
      <property name="javax.persistence.jdbc.url"    value="jdbc:hsqldb:mem:test" />
      <property name="javax.persistence.jdbc.user" value="sa" />
      <property name="javax.persistence.jdbc.password" value="" />
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
      <property name="show_sql" value="true"/>
      <property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/>
    </properties>
  </persistence-unit>
</persistence>
 

Я получаю это сообщение об ошибке:

   Jun 28, 2014 7:53:27 PM org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
Jun 28, 2014 7:53:27 PM org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
Jun 28, 2014 7:53:27 PM org.hibernate.ejb.HibernatePersistence logDeprecation
WARN: HHH015016: Encountered a deprecated javax.persistence.spi.PersistenceProvider [org.hibernate.ejb.HibernatePersistence]; use [org.hibernate.jpa.HibernatePersistenceProvider] instead.
Jun 28, 2014 7:53:27 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
INFO: HHH000204: Processing PersistenceUnitInfo [
    name: test
    ...]
Jun 28, 2014 7:53:27 PM org.hibernate.Version logVersion
INFO: HHH000412: Hibernate Core {4.3.5.Final}
Jun 28, 2014 7:53:27 PM org.hibernate.cfg.Environment <clinit>
INFO: HHH000206: hibernate.properties not found
Jun 28, 2014 7:53:27 PM org.hibernate.cfg.Environment buildBytecodeProvider
INFO: HHH000021: Bytecode provider name : javassist
Jun 28, 2014 7:53:28 PM org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit>
INFO: HCANN000001: Hibernate Commons Annotations {4.0.4.Final}
Jun 28, 2014 7:53:28 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
WARN: HHH000402: Using Hibernate built-in connection pool (not for production use!)
Jun 28, 2014 7:53:28 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000401: using driver [org.hsqldb.jdbcDriver] at URL [jdbc:hsqldb:mem:test]
Jun 28, 2014 7:53:28 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000046: Connection properties: {user=sa}
Jun 28, 2014 7:53:28 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator
INFO: HHH000006: Autocommit mode: false
Jun 28, 2014 7:53:28 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure
INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Jun 28, 2014 7:53:28 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.HSQLDialect
Jun 28, 2014 7:53:28 PM org.hibernate.engine.jdbc.internal.LobCreatorBuilder useContextualLobCreation
INFO: HHH000422: Disabling contextual LOB creation as connection was null
Initial SessionFactory creation failed.javax.persistence.PersistenceException: [PersistenceUnit: test] Unable to build Hibernate SessionFactory
Exception in Application constructor
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:367)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:305)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class handwrittencode.eiar.MainApp
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:884)
    at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:56)
    at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:158)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
    at com.sun.javafx.application.LauncherImpl$7.run(LauncherImpl.java:791)
    at com.sun.javafx.application.PlatformImpl$7.run(PlatformImpl.java:335)
    at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:301)
    at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:298)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:298)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
    at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
    ... 1 more
Caused by: java.lang.ExceptionInInitializerError
    at handwrittencode.eiar.util.EntityManagerUtil.<clinit>(EntityManagerUtil.java:16)
    at handwrittencode.eiar.MainApp.<init>(MainApp.java:32)
    ... 15 more
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: test] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:1225)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.access$600(EntityManagerFactoryBuilderImpl.java:119)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:853)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
    at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:397)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
    at org.hibernate.jpa.HibernatePersistenceProvider.createEntityManagerFactory(HibernatePersistenceProvider.java:75)
    at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:54)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:39)
    at handwrittencode.eiar.util.EntityManagerUtil.<clinit>(EntityManagerUtil.java:12)
    ... 16 more
Caused by: org.hibernate.MappingException: Could not determine type for: javafx.beans.property.StringProperty, at table: PROJECT, for columns: [org.hibernate.mapping.Column(projectAddress)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:336)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:310)
    at org.hibernate.mapping.Property.isValid(Property.java:241)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:496)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
    at org.hibernate.cfg.Configuration.validate(Configuration.java:1358)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1849)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
    ... 24 more
Exception running application handwrittencode.eiar.MainApp
 

Редактировать

 package handwrittencode.eiar.model;

import java.time.LocalDate;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import handwrittencode.eiar.util.LocalDateAdapter;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;


@Entity
@Table(name = "PROJECT")
public class Project {


     @Id
     @GeneratedValue(strategy = GenerationType.AUTO)
     @Column(name = "PROJECTID")
     private long projectId;

     private final StringProperty projectName;
     private final StringProperty projectJIBP;
     private final StringProperty projectState;
     private final StringProperty projectAddress;
     private final StringProperty projectManager;

     private final ObjectProperty<LocalDate> projectCreated;
     private final ObjectProperty<LocalDate> projectStart;
     private final ObjectProperty<LocalDate> projectEnd;


     public Project()
     {
         this(null,null,null,null,null);
     }

     public Project(String projectName, String projectJIBP, String projectState, String projectAddress, String projectManager)
     {
         this.projectName =  new SimpleStringProperty(projectName);
         this.projectJIBP =  new SimpleStringProperty(projectJIBP);
         this.projectState =  new SimpleStringProperty(projectState);
         this.projectAddress = new SimpleStringProperty(projectAddress);
         this.projectManager = new SimpleStringProperty(projectManager);


         this.projectCreated =  new SimpleObjectProperty<LocalDate>(LocalDate.of(1999, 2, 21));
         this.projectStart = new SimpleObjectProperty<LocalDate>(LocalDate.of(1999, 2, 21));
         this.projectEnd = new SimpleObjectProperty<LocalDate>(LocalDate.of(1999, 2, 21));




     }


     @Column(name = "PROJECTNAME")
     public String getProjectName() {
            return projectName.get();
     }

     public void setProjectName(String projectName) {
            this.projectName.set(projectName);
     }

     public StringProperty projectNameProperty() {
            return this.projectName;
     }

     /**/

     @Column(name = "PROJECTJIBP")
     public String getProjectJIBP(){
         return projectJIBP.get();
     }

     public void setProjectJIBP(String projectJIBP) {
            this.projectJIBP.set(projectJIBP);
     }

     public StringProperty projectJIBPProperty() {
            return this.projectJIBP;
     }

   /**/

     @Column(name = "PROJECTSTATE")
     public String getProjectState(){
         return projectState.get();
     }

     public void setProjectState(String projectState) {
            this.projectState.set(projectState);
     }

     public StringProperty projectStateProperty() {
            return this.projectState;
     }

     /**/

     @Column(name = "PROJECTADDRESS")
     public String getProjectAddress(){
         return projectAddress.get();
     }

     public void setProjectAddress(String projectAddress) {
            this.projectAddress.set(projectAddress);
     }

     public StringProperty projectAddressProperty() {
            return this.projectAddress;
     }

     /**/

     @Column(name = "PROJECTMANAGER")
     public String getProjectManager(){
         return projectManager.get();
     }

     public void setProjectManager(String projectManager) {
            this.projectManager.set(projectManager);
     }

     public StringProperty projectManagerProperty() {
            return this.projectManager;
     }


     /**/

     @XmlJavaTypeAdapter(LocalDateAdapter.class)
        public LocalDate getProjectCreated() {
            return projectCreated.get();
        }

        public void setProjectCreated(LocalDate projectCreated) {
            this.projectCreated.set(projectCreated);
        }

        public ObjectProperty<LocalDate> projectCreatedProperty() {
            return projectCreated;
        }


     /**/

     @XmlJavaTypeAdapter(LocalDateAdapter.class)
        public LocalDate getProjectStart() {
            return projectStart.get();
        }

        public void setProjectStart(LocalDate projectStart) {
            this.projectStart.set(projectStart);
        }

        public ObjectProperty<LocalDate> projectStartProperty() {
            return projectStart;
        }

      /**/

        @XmlJavaTypeAdapter(LocalDateAdapter.class)
        public LocalDate getProjectEnd() {
            return projectEnd.get();
        }

        public void setProjectEnd(LocalDate projectEnd) {
            this.projectEnd.set(projectEnd);
        }

        public ObjectProperty<LocalDate> projectEndProperty() {
            return projectEnd;
        }


}
 

Ответ №1:

Является ли это допустимым способом использования гибернации с JavaFX?

Нет: используйте доступ к свойствам вместо доступа к полю:

 private final StringProperty projectName;

@Column(name = "PROJECTNAME")
public final String getProjectName() {
    return projectName.get();
}

public final void setProjectName(String projectName) {
    this.projectName.set(projectName);
}

public StringProperty projectNameProperty() {
    return projectName;
}
 

и т.д…

Это позволяет Hibernate определять типы из возвращаемых типов методов get, а не из типов фактических полей; поэтому он может сохранять String s вместо StringProperty s и так далее.

См. Блог Стивена Ван Импа и мой блог

Комментарии:

1. Большое вам спасибо. Я попробую это. 🙂

2. Смешивать типы доступа без их явного указания рискованно: у вас есть доступ к полю и доступ к projectId свойствам для других полей. Если вы хотите сохранить идентификатор, используя доступ к полю, следуйте примеру в разделе «смешивание типов доступа» в блоге Стивена Ван Импе. (Я предполагаю, что вы видите ту же ошибку.)

3. Теперь программа запускается, больше никаких ошибок. Просто ПРЕДУПРЕЖДАЮ: WARN: HHH015016: Обнаружен устаревший javax.persistence.spi.PersistenceProvider