当前位置: 首页 > news >正文

Maven 和 gradle JavaFX 项目的休眠行为差异

我一直在尝试将Hibernate与我的JavaFX Maven项目集成。它与Hibernate社区包、Jakartaxerial配合得很好。我还将persistence.xml文件放在了src/main/resources/META-INF/persistence.xml

我还尝试使用gradle创建另一个项目,并按照此maven项目的步骤操作,但出现了错误No Persistence provider for EntityManager named demo。对于 gradle javafx项目,它persistence.xmlmaven项目位于同一位置

pom.xml供您参考

<dependency><groupId>org.xerial</groupId><artifactId>sqlite-jdbc</artifactId><version>3.46.1.0</version></dependency><!-- https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-community-dialects --><dependency><groupId>org.hibernate.orm</groupId><artifactId>hibernate-community-dialects</artifactId><version>6.6.0.Final</version></dependency><!-- https://mvnrepository.com/artifact/jakarta.persistence/jakarta.persistence-api --><dependency><groupId>jakarta.persistence</groupId><artifactId>jakarta.persistence-api</artifactId><version>3.1.0</version></dependency>

persistence.xml供参考

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"><persistence-unit name="demo" transaction-type="RESOURCE_LOCAL"><provider>org.hibernate.jpa.HibernatePersistenceProvider</provider><properties><property name="hibernate.connection.driver_class" value="org.sqlite.JDBC"/><property name="hibernate.connection.url" value="jdbc:sqlite:ms.db"/><property name="hibernate.dialect" value="org.hibernate.community.dialect.SQLiteDialect"/><property name="hibernate.connection.username" value=""/><property name="hibernate.connection.password" value=""/><property name="hibernate.temp.use_jdbc_metadata_defaults" value="false"/></properties></persistence-unit>
</persistence>

build.gradle的另一个项目是

javafx {version = '17.0.6'modules = ['javafx.controls', 'javafx.fxml']
}dependencies {// https://mvnrepository.com/artifact/org.hibernate.orm/hibernate-community-dialectsimplementation 'org.hibernate.orm:hibernate-community-dialects:6.6.0.Final'// https://mvnrepository.com/artifact/jakarta.persistence/jakarta.persistence-apiimplementation 'jakarta.persistence:jakarta.persistence-api:3.2.0'// https://mvnrepository.com/artifact/org.xerial/sqlite-jdbcimplementation 'org.xerial:sqlite-jdbc:3.46.1.0'testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
}

而持久性单元的拼写也是正确的。

我尝试从build.gradle中获取sourceSets,结果显示有关重复的错误,我得出的结论是所有资源文件都已包含在内。我还降级了一些版本,它确实有效。如何解决mavengradle之间的这种行为差异?我见过一些使用,hibernate.cfg.xml哪个最适合持久化或休眠xml文件?

解决方案

这不是对您的问题的直接回答,所以如果您不想使用该方法,请忽略它。

推荐

您正在尝试将本地嵌入式数据库技术与JavaFX结合使用。对我来说(对其他人来说会有所不同),最好使用以下方法:

使用比Hibernate更高级别的DB API(例如Spring Data)。
使用本机Java嵌入式数据库而不是SQLLite(例如H2)。

笔记

在幕后,它仍然是一个使用Hibernate访问嵌入式数据库的Maven项目,但 Maven依赖项和数据库配置任务均由Spring Boot Data启动器依赖项和Spring Boot的自动配置处理,这些自动配置来自输入application.yaml配置和应用程序中的注释驱动配置。因此,您无需定义persistence.xml之类的内容、单独的Hibernate属性文件、编写样板DAO代码、提供hibernate.cfg.xml等。

缺点是您在应用程序之上添加了几层抽象,这可能会带来进一步的混乱、学习和复杂性。但是,在我看来,如果您要花时间学习使用JavaFX API进行 JPA开发,那么您不妨让Spring完成一些工作,同时学习一些Spring。只需一步一步来,专注于您当前需要学习的东西来解决您遇到的每个问题,而不是试图学习“所有”Spring

使用这样的嵌入式数据库是客户端应用程序的特定(且有效)模型。但是,许多客户端应用程序(例如几乎所有基于HTMLWeb应用程序,以及许多独立应用程序,如JavaFX应用程序或移动原生应用程序)不使用嵌入式数据库,而是让客户端与共享Web服务器通信(通常使用REST API),数据库集成在服务器端而不是客户端。因此,请考虑您的应用程序是否确实遵循适合您目的的架构模型。

例子

无论如何,这里有一个示例项目,如果您对这种方法感兴趣的话。

本示例使用:
JavaFX (JPA Repo、服务) 中添加Spring依赖注入

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.3.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>org.example</groupId><artifactId>FXSpringData</artifactId><version>1.0-SNAPSHOT</version><name>FXSpringData</name><properties><java.version>22</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.openjfx</groupId><artifactId>javafx-controls</artifactId><version>22.0.2</version></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>
</project>

src/main/资源/应用程序.yaml

spring:datasource:url: jdbc:h2:mem:mydb# use this url for a file db named demo stored in the user home dir.# url: jdbc:h2:file:~/demousername: sapassword: passworddriverClassName: org.h2.Driverjpa:defer-datasource-initialization: trueh2:# console is at: http://localhost:8080/h2-console, after app loadedconsole:enabled: truesettings:trace: falseweb-allow-others: false

src/main/资源/数据.sql

INSERT INTO countries (id, name) VALUES (1, 'USA');
INSERT INTO countries (id, name) VALUES (2, 'France');
INSERT INTO countries (id, name) VALUES (3, 'Brazil');
INSERT INTO countries (id, name) VALUES (4, 'Italy');
INSERT INTO countries (id, name) VALUES (5, 'Canada');

src/main/java/org/esample/fxspringdata/SpringApp.java

package org.example.fxspringdata;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class FXApp {    public static void main(String[] args) {SpringApplication.run(SpringApp.class, args);}   
}

src/main/java/org/esample/fxspringdata/FXApp.java

package org.example.fxspringdata;import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import org.example.fxspringdata.dao.CountryRepository;
import org.example.fxspringdata.model.Country;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;public class FXApp extends Application {private ConfigurableApplicationContext springContext;@Autowiredprivate CountryRepository countryRepository;@Overridepublic void init() {springContext = SpringApplication.run(SpringApp.class);springContext.getAutowireCapableBeanFactory().autowireBeanProperties(this,AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE,true);}@Overridepublic void start(Stage stage) {ListView<Country> countriesListView = new ListView<>(FXCollections.observableArrayList(countryRepository.findAll()));countriesListView.setCellFactory(_ -> new CountryListCell());countriesListView.setPrefSize(100, 100);VBox layout = new VBox(10,new Label("Countries from DB"),countriesListView);layout.setPadding(new Insets(10));stage.setScene(new Scene(layout));stage.show();}@Overridepublic void stop() {springContext.stop();}public static void main(String[] args) {launch(args);}
}

src/main/java/org/esample/fxspringdata/CountryListCell.java

package org.example.fxspringdata;import javafx.scene.control.ListCell;
import org.example.fxspringdata.model.Country;public final class CountryListCell extends ListCell<Country> {@Overrideprotected void updateItem(Country item, boolean empty) {super.updateItem(item, empty);if (empty || item == null) {setText(null);return;}setText(item.getName());}
}

src/main/java/org/esample/fxspringdata/model/Country.java

package org.example.fxspringdata.model;import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.util.Objects;@Table(name = "countries")
@Entity
public class Country {@Id@GeneratedValueprivate int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic boolean equals(Object o) {if (this == o)return true;if (o == null || getClass() != o.getClass())return false;Country country = (Country) o;return id == country.id && name.equals(country.name);}@Overridepublic int hashCode() {return Objects.hash(id, name);}@Overridepublic String toString() {return "Country{" +"id=" + id +", name='" + name + '\'' +'}';}
}

src/main/java/org/esample/fxspringdata/dao/CountryRepository.java

package org.example.fxspringdata.dao;import org.example.fxspringdata.model.Country;
import org.springframework.data.jpa.repository.JpaRepository;public interface CountryRepository extends JpaRepository<Country, Integer> {}

执行

我使用Idea,将项目配置为非模块化项目(未定义module-info.java)执行,与Maven中定义的版本匹配的JavaFX SDK单独下载,以便可以轻松配置模块路径和JavaFX运行时组件。
在这里插入图片描述
关键部分是VM参数(不是程序参数):

--module-path <pathtojavafx>/javafx-sdk-22.0.2/lib --add-modules javafx.controls

<pathtojavafx>用您机器上的JavaFX SDK的位置进行替换。

应用程序的功能一旦运行,该应用程序将:

启动Spring/Hibernate/H2嵌入式数据库。
使用从实体派生的模式初始化数据库(创建所需的“国家/地区”表)。
将提供的种子数据插入数据库。
使用Spring Data读取数据(Spring Data又使用Hibernate通过Hikari连接池的 H2 JDBC驱动程序访问数据库)。
JavaFX列表视图中显示国家列表。
在这里插入图片描述


http://www.mrgr.cn/news/30602.html

相关文章:

  • 2024java面试-软实力篇
  • VMware Workstation Pro 17下载及安装教程
  • 828华为云征文|华为Flexus云服务器打造 mediacms 线上影院
  • JS和Node.js的事件循环
  • 计算生物学:概念、历史、现状与展望?
  • iostat 命令:系统状态监控
  • 典型的MVC设计模式:使用JSP和JavaBean相结合的方式来动态生成网页内容典型的MVC设计模式
  • Springboot的三层架构
  • JDK自带的序列化
  • C++ : 继承问题 [virtual函数调用,为什么禁止在virtual使用默认参数]
  • 向上转移和向下转型
  • U盘显示未被格式化:深入解析、恢复策略与预防之道
  • 网络安全 DVWA通关指南 DVWA Stored Cross Site Scripting (存储型 XSS)
  • 蓝桥杯嵌入式客观题合集
  • 【字符函数】strcpy函数(字符串复制函数)+strcat函数(字符串追加)+strcmp函数(字符串比较)【笔记】
  • 英飞凌最新AURIX™TC4x芯片介绍
  • Lecture 4 Page Table
  • C++—string类接口与用法大总结(其中涉及STL基础)
  • 【Vmware16安装教程】
  • 登录后继续执行方法