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

news2024/9/20 5:21:56

我一直在尝试将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-dialects
  implementation 'org.hibernate.orm:hibernate-community-dialects:6.6.0.Final'

  // https://mvnrepository.com/artifact/jakarta.persistence/jakarta.persistence-api
  implementation 'jakarta.persistence:jakarta.persistence-api:3.2.0'

  // https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc
  implementation '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:~/demo
    username: sa
    password: password
    driverClassName: org.h2.Driver
  jpa:
    defer-datasource-initialization: true
  h2:
    # console is at: http://localhost:8080/h2-console, after app loaded
    console:
      enabled: true
      settings:
        trace: false
        web-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;

    @Autowired
    private CountryRepository countryRepository;

    @Override
    public void init() {
        springContext = SpringApplication.run(SpringApp.class);
        springContext
                .getAutowireCapableBeanFactory()
                .autowireBeanProperties(
                        this,
                        AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE,
                        true
                );
    }

    @Override
    public 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();
    }

    @Override
    public 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> {
    @Override
    protected 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
    @GeneratedValue
    private 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;
    }

    @Override
    public 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);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }

    @Override
    public 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.coloradmin.cn/o/2148010.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《高等代数》行列式转置(应用)

说明&#xff1a;此文章用于本人复习巩固&#xff0c;如果也能帮助到大家那就更加有意义了。 注&#xff1a;1&#xff09;“行列式转置值不变”这一性质在求解行列式的过程中也有极大的作用。

代码随想录算法训练营第51天 | 岛屿数量、岛屿的最大面积

目录 岛屿数量 题目描述 输入描述 输出描述 输入示例 输出示例 提示信息 1. 深搜解法 2. 广搜解法 岛屿的最大面积 题目描述 输入描述 输出描述 输入示例 输出示例 提示信息 1. 深搜解法 2. 广搜解法 岛屿数量 题目描述 给定一个由 1&#xff08;陆地&…

Python和C++气候模型算法模型气候学模拟和统计学数据可视化及指标评估

&#x1f3af;要点 贝叶斯推理气候模型辐射对流及干湿能量平衡模型时间空间气象变化预测模型评估统计指标气象预测数据变换天气和气象变化长短期影响预估降低气候信息尺度评估算法气象行为模拟&#xff1a;碳循环、辐射强迫和温度响应温室气体排放碳循环温室诱导气候变化评估气…

影刀RPA实战:网页爬虫之苦瓜书籍数据

书籍常常被视为心灵的慰藉&#xff0c;因为它们能够在不同的层面上为人们提供支持和安慰。 1. 书籍对我们的重要性 书籍是人类知识的载体&#xff0c;也是智慧的结晶。它们不仅是学习的工具&#xff0c;更是人类心灵的慰藉。在忙碌的生活中&#xff0c;书籍能够提供知识、启发…

VMWare17.5.2中Windows7企业版安装VMWareTools失败及解决办法

一、问题产生环境 宿主机系统&#xff1a;Windows11专业版 x64 虚拟机版本&#xff1a;VMWare17.5.2 虚拟机系统&#xff1a;Windows 7企业版 x64&#xff08;sp1纯净版&#xff09; 二、问题表现现象 在Windows 7企业版系统安装完成后&#xff0c;点击虚拟机编辑&#xff0c;…

安科瑞智能塑壳断路器适用于物联网配电电网中-安科瑞黄安南

智能塑壳断路器是一款多功能、体积小、智能化的塑壳断路器&#xff0c;适用于物联网配电电网中。用于三相四线中性点直接接地的供电、用电系统&#xff0c;能全面采集功率、电能量、功率因数、谐波等用电参数;具有过载、短路、缺相、过压、欠压、剩余电流动作保护等功能&#x…

vscode 环境搭建

1. 插件离线安装 官网链接是&#xff1a;https://marketplace.visualstudio.com/vscode 下载需要的插件&#xff1a; vscode 离线安装 在打开的文件中选择扩展包&#xff0c;点击安装即可 2. 故障解决 参考&#xff1a;https://blog.csdn.net/weixin_63712639/article/det…

Modbus_RTU和Modbus库

目录 一.Modbus_RTU 1. 与Modbus TCP的区别 2. Modbus RTU特点 3. Modbus RTU协议格式 4. 报文详解 5. 代码实现RTU通信 1. 打开模拟的RTU从机 2. linux端使用代码实现和串口连接 2.1. 框架搭建 2.2 代码 二.Modbus库 1.库函数 一.Modbus_RTU 1. 与Modbus T…

el-form中三级动态添加数据

el-form中三级动态添加数据 data数据view按钮触发事件 data数据 submitForm: {id: undefined, //修改IDapp_id: undefined, //IP类型name: , //规则名称sort: undefined, //排序detail: [{keycode: 0,title_one: undefined, //一级标题desc_detail: [{keycode: 0,title_two: u…

vue之我不会 计算属性 vuex 路由 插槽

一、计算属性 例子&#xff1a; 注意&#xff1a;调用计算属性时&#xff0c;不可以带括号&#xff0c;那样调用的就是方法&#xff0c;如&#xff1a;以下调用fullName时不可funnName() <div id"root">姓&#xff1a;<input type"text" v-model&…

iotop 命令:磁盘IO监控和诊断

一、命令简介 ​iotop​命令用于监视磁盘I/O&#xff0c;实时显示每个进程或线程的读写速率等信息。非常适合用于诊断系统中的I/O瓶颈。 ‍ ​​ ‍ 安装 iotop 在大多数Linux发行版中&#xff0c;iotop​可能不是预装的。可以使用包管理器来安装它。 例如&#xff0c;在…

C#|.net core 基础 - 扩展数组添加删除性能最好的方法

今天在编码的时候遇到了一个问题&#xff0c;需要对数组变量添加新元素和删除元素&#xff0c;因为数组是固定大小的&#xff0c;因此对新增和删除并不友好&#xff0c;但有时候又会用到&#xff0c;因此想针对数组封装两个扩展方法&#xff1a;新增元素与删除元素&#xff0c;…

MySQL5.7.42高可用MHA搭建及故障切换演示

系列文章目录 rpmbuild构建mysql5.7RPM安装包 MySQL基于GTID同步模式搭建主从复制 文章目录 系列文章目录前言一、MHA架构介绍1.MHA的功能2.MHA组成3.MHA故障转移过程4.MHA架构优缺点 二、环境准备1.服务器免密2.基于GTID主从复制搭建3.下载mha组件 三、MHA组件安装1.安装依赖…

数据结构——C语言单链表的实现

单链表的实现 一.链表的节点二.如何在在链表中插入数据1.尾插2.改进3.头插4.指定位置pos&#xff0c;在pos前插入数据 三 .删除数据1.头删2.尾删3.指定位置删除数据 一.链表的节点 //链表中的数据类型,方便后续的更改 typedef int SLTDatatype;//链表的节点 typedef struct SL…

学习ROS2第一天—新手笔记(humble版本)

————今早七点达到实验室&#xff0c;吃了早饭收拾了一下现在07&#xff1a;24开始学习———— 1. RO2与ROS1的不同架构&#xff1a; ROS1架构下&#xff0c;所有节点都是Master进行管理 ROS使用基于DDS的Discovery机制&#xff0c;和Master说再见 API的重新设计 编译…

查看ip地址的方法有几种?探索多样方法

在当今数字化时代&#xff0c;IP地址作为网络设备的唯一标识符&#xff0c;在网络连接、数据传输、网络安全等方面扮演着至关重要的角色。无论是普通用户进行网络设置&#xff0c;还是网络管理员进行故障排查&#xff0c;了解如何查看IP地址都是一项基础且必备的技能。本文将深…

2-99 基于matlab多尺度形态学提取眼前节组织

基于matlab多尺度形态学提取眼前节组织&#xff0c;通过应用不同尺度的结构元素进行边缘检测&#xff0c;再通过加权融合的思想来整合检测到的边缘&#xff0c;降低图像噪声的影响&#xff0c;提高边缘检测的精度。程序已调通&#xff0c;可直接运行。 下载源程序请点链接&…

18.DHT11编程案例

温湿度传感器 产品概述 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器&#xff0c;应用领域&#xff1a;暖通 空调&#xff1b;汽车&#xff1b;消费品&#xff1b;气象站&#xff1b;湿度调节器&#xff1b;除湿器&#xff1b;家电&#xff1b;医疗…

傅里叶变换的基本性质和有关定理

一、傅里叶变换的基本性质 1.1 线性性质 若 则 其中:a,b是常数 函数线性组合的傅里叶变换等于歌函数傅里叶变换的相应组合。 1.2 对称性 若 则 关于傅里叶变换的对称性还有 虚、实、奇、偶函数的傅里叶变换性质: 1.3 迭次傅里叶变换 对f(x,y)连续两次做二维傅里叶变换…

shell指令及笔试题

一&#xff1a;linux基本指令考察 创建文件&#xff0c;直接在本目录的上级目录下创建一个名为dir1的文件夹&#xff0c;并在dir1文件夹下创建一个名为file1的文件 答&#xff1a;本目录的上级目录下创建一个名为dir1的文件:mkdir ../dir1 在dir1文件夹下创建一个名为file1的…