RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1026006
Accepted
isnullxbh
isnullxbh
Asked:2020-09-19 21:23:13 +0000 UTC2020-09-19 21:23:13 +0000 UTC 2020-09-19 21:23:13 +0000 UTC

休眠:错误持久化实体实例

  • 772

资源:

Transaction tx = null;
try (final var session = HibernateSessionFactory.getInstance().openSession()) {
    tx = session.beginTransaction();
    session.save(c); // где с - экземпляр класса InternalDatabase
    tx.commit();
} catch (Exception ex) {
    logger.error("cannot save DB connection: {}", ex.getMessage());
    if (tx != null && (tx.getStatus() == TransactionStatus.ACTIVE || tx.getStatus() == TransactionStatus.MARKED_ROLLBACK)) {
        try {
            tx.rollback();
        } catch (Exception nex) {
            logger.error(nex.getMessage());
        }
    }
}

错误:

19:26:28.595 [JavaFX 应用程序线程] 错误 com.xxx.DatabaseConnectionsController - 无法保存数据库连接:类 org.hibernate.id.IdentifierGeneratorHelper$2 无法转换为类 java.lang.Long (org.hibernate.id.IdentifierGeneratorHelper$2在加载程序“app”的模块 org.hibernate.orm.core@6.0.0.Alpha2 中;java.lang.Long 在加载程序“bootstrap”的模块 java.base 中)

内部数据库:

@Entity
@Table(name = "internal_database")
public class InternalDatabase {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    @Column(name = "name", nullable = false, unique = true)
    private String name;

    @Column(name = "conn_str", nullable = false)
    private String connectionString;

    @Column(name = "username")
    private String username;

    @Column(name = "password")
    private String password;

    @Column(name = "query")
    private String query;

    public InternalDatabase() { }
}

一开始,我手动创建了表格:

-- Entity: InternalDatabase
CREATE TABLE IF NOT EXISTS INTERNAL_DATABASE (
    ID          INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    NAME        VARCHAR(100)    NOT NULL,
    CONN_STR    VARCHAR(300)    NOT NULL,
    USERNAME    VARCHAR(100)    NOT NULL,
    PASSWORD    VARCHAR(100)    NOT NULL,
    QUERY       VARCHAR(500)    DEFAULT ''
);

ALTER TABLE "INTERNAL_DATABASE"
    ADD CONSTRAINT INTERNAL_DATABASE_NAME UNIQUE (NAME);

,然后hbm2ddl.auto在 Hibernate 配置文件中添加了一个选项 - 表是自动创建的,错误仍然存​​在。

hibernate.cfg.xml 看起来像这样:

<hibernate-configuration xmlns="http://www.hibernate.org/xsd/orm/cfg">
    <session-factory>
        <property name="connection.url">jdbc:h2:file:./xa;ifexists=true</property>
        <property name="connection.driver_class">org.h2.Driver</property>
        <property name="dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="show_sql">true</property>
<!--        <property name="hbm2ddl.auto">create</property>-->

        <mapping class="com.xxx.entity.Permission"/>
        <mapping class="com.xxx.entity.Role"/>
        <mapping class="com.xxx.entity.User"/>
        <mapping class="com.xxx.entity.InternalDatabase"/>
    </session-factory>
</hibernate-configuration>

环境:macOS 10.13、10.14;JVM12;休眠 6.0.0Alpha2;H2

MWE:https ://github.com/isnullxbh/hhh-13630

java
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Mikita Berazouski
    2020-09-21T04:55:01Z2020-09-21T04:55:01Z

    如果我没记错的话,那么这里的问题是生成器无法在没有物理插入的情况下生成标识符,而是使用一种标记。就我而言,类似的代码适用于 Oracle,但不适用于 H2。

    作为解决方案之一,请尝试使用@GeneratedValue(strategy = GenerationType.AUTO), 或一般@GeneratedValue. 如果由于某种原因建议的选项不起作用,则使用其他类型的生成器,例如,@GenericGenerator(那里的一切都应该是平滑的)。

    • 1
  2. Best Answer
    Antonio112009
    2020-09-21T06:50:40Z2020-09-21T06:50:40Z
    1. 如果您使用的是 Maven,请安装数据库连接提供程序。就个人而言,我使用hikariCP,但很多人使用C3P0(?!?)。我发现hikari更快。
      PS选择与您相关的版本)
            <dependency>
                <groupId>com.zaxxer</groupId>
                <artifactId>HikariCP</artifactId>
                <version>3.3.1</version>
            </dependency>
    
            <dependency>
                <groupId>org.hibernate</groupId>
                <artifactId>hibernate-hikaricp</artifactId>
                <version>5.4.2.Final</version>
            </dependency>
    
    1. 我会推荐以下设置hibernate.cfg.xml:

    休眠.cfg.xml

    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <!-- JDBC Database connection settings -->
            <property name="connection.driver_class">org.h2.Driver</property>
            <property name="connection.url">jdbc:h2:file:./xa;ifexists=true</property>
    
            <property name="connection.provider_class">org.hibernate.hikaricp.internal.HikariCPConnectionProvider</property>
            <property name="hibernate.hikari.connectionTimeout">20000</property>
            <property name="hibernate.hikari.minimumIdle">10</property>
            <property name="hibernate.hikari.maximumPoolSize">20</property>
            <property name="hibernate.hikari.idleTimeout">300000</property>
    
            <!-- Select our SQL dialect -->
            <property name="dialect">org.hibernate.dialect.H2Dialect</property>
    
            <!-- Echo the SQL to stdout -->
            <!--<property name="show_sql">true</property>-->
            <property name="show_sql">false</property>
    
            <!-- Set the current session context -->
            <property name="current_session_context_class">thread</property>
    
            <!-- Drop and re-create the database schema on startup -->
            <!--<property name="hbm2ddl.auto">create</property>-->
            <!--<property name="hbm2ddl.auto">create-drop</property>-->
            <!--<property name="hbm2ddl.auto">update</property>-->
            <!--<property name="hbm2ddl.auto">validate</property>-->
    
            <!-- dbcp connection pool configuration -->
            <property name="hibernate.dbcp.initialSize">5</property>
            <property name="hibernate.dbcp.maxTotal">20</property>
            <property name="hibernate.dbcp.maxIdle">10</property>
            <property name="hibernate.dbcp.minIdle">5</property>
            <property name="hibernate.dbcp.maxWaitMillis">-1</property>
    
    
            <mapping class="com.xxx.entity.Permission"/>
            <mapping class="com.xxx.entity.Role"/>
            <mapping class="com.xxx.entity.User"/>
            <mapping class="com.xxx.entity.InternalDatabase"/>
    
        </session-factory>
    </hibernate-configuration>
    
    1. 相反,我GenerationType.IDENTITY建议使用Sequence,甚至自定义))在我的问题中,我试图清楚地描述如何设置这个东西。该问题的答案基于此站点的材料。

    2. 设置以下设置HibernateUtil:

    HibernateUtil.java:

    import org.hibernate.SessionFactory;
    import org.hibernate.boot.Metadata;
    import org.hibernate.boot.MetadataSources;
    import org.hibernate.boot.registry.StandardServiceRegistry;
    import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
    
    public class HibernateUtil {
        private static StandardServiceRegistry registry;
        private static SessionFactory sessionFactory;
    
        public static SessionFactory getSessionFactory() {
            if (sessionFactory == null) {
                try {
                    // Create registry
                    registry = new StandardServiceRegistryBuilder().configure().build();
    
                    // Create MetadataSources
                    MetadataSources sources = new MetadataSources(registry);
    
                    // Create Metadata
                    Metadata metadata = sources.getMetadataBuilder().build();
    
                    // Create SessionFactory
                    sessionFactory = metadata.getSessionFactoryBuilder().build();
    
                } catch (Exception e) {
                    e.printStackTrace();
                    if (registry != null) {
                        StandardServiceRegistryBuilder.destroy(registry);
                    }
                }
            }
            return sessionFactory;
        }
    
        public static void shutdown() {
            if (registry != null) {
                StandardServiceRegistryBuilder.destroy(registry);
            }
        }
    }
    
    1. 将对象保存到表的示例:
    public class UserRepository {
        private Transaction transaction = null;
        private Session session = null;
        private User user = null;
    
        //Save Single User
        public void saveUser(User user) {
            try {
                session = HibernateUtil.getSessionFactory().openSession();
                transaction = session.beginTransaction();
    
                session.saveOrUpdate(user);
    
                transaction.commit();
    
                session.clear();
                session.close();
    
            } catch (Exception e) {
                if (transaction != null) {
                    transaction.rollback();
                }
                e.printStackTrace();
            }
        }
    }
    
    1. 为什么saveOrUpdate而不是save?为了不创建两种方法,一种保存数据,另一种更改它们。通过一种方法更容易实现

    2. @Table(name = "internal_database")- 不必写列/表的名称。如果你有一个变量写成MyBestFriends,那么在创建表/列时,hibernate 会将它写成my_best_friends.

    3. (可选)您@Column也可以不提及它,因为正如我个人注意到的那样,hibernate 类中的任何变量都已被视为列。(除非您使用 @transient 注释)。我无法用任何资源证实这一事实......所以@Column无论如何最好写

    4. @Column(nullable = false) 与 @NotNull。您应该使用@NotNull,因为在这种情况下,null-object 内容检查发生在数据发送到数据库之前。您可以在此处阅读此信息

    5. (可选)我不太确定,但如果你private Sting name的是独一无二的,也许你可以给它添加一个注释@NaturalId。关于它的一点写在这里。

    6. (可选)如果您对注释有疑问,可以阅读此问题的答案。虽然答案并不完美。

    结果,我大致是这样看待你的本质的:

    @Entity
    @Table
    public class InternalDatabase {
    
        @Id
        @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "intdata_generator")
        @SequenceGenerator(name="intdata_generator", sequenceName = "seq_intdata", allocationSize = 1, initialValue = 1)
        private Long id;
    
        @NotNull
        @Column(unique = true)
        private String name;
    
        @NotNull
        @Column(name = "conn_str",)
        private String connectionString;
    
        @Column
        private String username;
    
        @Column
        private String password;
    
        @Column
        private String query;
    
        public InternalDatabase() { }
    }
    
    • 1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    根据浏览器窗口的大小调整背景图案的大小

    • 2 个回答
  • Marko Smith

    理解for循环的执行逻辑

    • 1 个回答
  • Marko Smith

    复制动态数组时出错(C++)

    • 1 个回答
  • Marko Smith

    Or and If,elif,else 构造[重复]

    • 1 个回答
  • Marko Smith

    如何构建支持 x64 的 APK

    • 1 个回答
  • Marko Smith

    如何使按钮的输入宽度?

    • 2 个回答
  • Marko Smith

    如何显示对象变量的名称?

    • 3 个回答
  • Marko Smith

    如何循环一个函数?

    • 1 个回答
  • Marko Smith

    LOWORD 宏有什么作用?

    • 2 个回答
  • Marko Smith

    从字符串的开头删除直到并包括一个字符

    • 2 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5