资源:
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
如果我没记错的话,那么这里的问题是生成器无法在没有物理插入的情况下生成标识符,而是使用一种标记。就我而言,类似的代码适用于 Oracle,但不适用于 H2。
作为解决方案之一,请尝试使用
@GeneratedValue(strategy = GenerationType.AUTO), 或一般@GeneratedValue. 如果由于某种原因建议的选项不起作用,则使用其他类型的生成器,例如,@GenericGenerator(那里的一切都应该是平滑的)。hikariCP,但很多人使用C3P0(?!?)。我发现hikari更快。PS选择与您相关的版本)
hibernate.cfg.xml:休眠.cfg.xml
相反,我
GenerationType.IDENTITY建议使用Sequence,甚至自定义))在我的问题中,我试图清楚地描述如何设置这个东西。该问题的答案基于此站点的材料。设置以下设置
HibernateUtil:HibernateUtil.java:
为什么
saveOrUpdate而不是save?为了不创建两种方法,一种保存数据,另一种更改它们。通过一种方法更容易实现@Table(name = "internal_database")- 不必写列/表的名称。如果你有一个变量写成MyBestFriends,那么在创建表/列时,hibernate 会将它写成my_best_friends.(可选)您
@Column也可以不提及它,因为正如我个人注意到的那样,hibernate 类中的任何变量都已被视为列。(除非您使用 @transient 注释)。我无法用任何资源证实这一事实......所以@Column无论如何最好写@Column(nullable = false) 与 @NotNull。您应该使用
@NotNull,因为在这种情况下,null-object 内容检查发生在数据发送到数据库之前。您可以在此处阅读此信息(可选)我不太确定,但如果你
private Sting name的是独一无二的,也许你可以给它添加一个注释@NaturalId。关于它的一点写在这里。(可选)如果您对注释有疑问,可以阅读此问题的答案。虽然答案并不完美。
结果,我大致是这样看待你的本质的: