Hibernate为什么偶尔会在持久执行select currval? [英] Why does Hibernate execute select currval in persist occasionally?
问题描述
有时候,似乎Hibernate在持久操作期间会像这样随机执行查询:
Sometimes and seems randomly Hibernate executes query like that during persist operation:
select currval('MY_TABLE_NAME_id_seq');
实体:
@Entity
@Table(name = "MY_TABLE_NAME")
public class MyEntity {
@Id
@Column(name = "ID", unique = true, nullable = false)
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Long id;
}
代码:
@Transactional
public void persistMyEntity(String name) {
MyEntity entity= new MyEntity (name);
sessionFactory.getCurrentSession().persist(entity);
}
生成的sql:
insert into MY_TABLE_NAME(name) values ('xyz');
select currval('MY_TABLE_NAME_id_seq');
但是通常不执行select currval
.有什么解释吗?
But usually select currval
is not executed. Is there any explanation about that?
顺便说一句,我的问题与此但问题中的解决方案不适用于我.
BTW my question is very similar to this but the solution in the question is not worked for me.
注意:
My_TABLE_NAME ddl sql:
My_TABLE_NAME ddl sql:
CREATE TABLE my_table_name (
id bigserial NOT NULL,
name character varying(256) NOT NULL,
CONSTRAINT my_table_name_id PRIMARY KEY (id)
);
休眠属性:
Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", HIBERNATE_DIALECT);
hibernateProperties.put("hibernate.show_sql", HIBERNATE_SHOW_SQL);
hibernateProperties.put("hibernate.hbm2ddl.auto", "none");
hibernateProperties.put("hibernate.connection.release_mode", "auto");
hibernateProperties.put("hibernate.archive.autodetection", ARCHIVE_AUTODETECTION);
hibernateProperties.put("hibernate.format_sql", true);
hibernateProperties.put("hibernate.use_sql_comments", true);
hibernateProperties.put("hibernate.generate_statistics", false);
hibernateProperties.put("hibernate.jdbc.use_scrollable_resultset", true);
hibernateProperties.put("hibernate.jdbc.use_streams_for_binary", true);
hibernateProperties.put("hibernate.jdbc.batch_size", 20);
hibernateProperties.put("hibernate.order_inserts", true);
hibernateProperties.put("hibernate.order_updates", true);
hibernateProperties.put("hibernate.jdbc.batch_versioned_data ", true);
hibernateProperties.put("hibernate.cache.region_prefix", "hibernate.cache");
hibernateProperties.put("hibernate.cache.use_query_cache", false);
hibernateProperties.put("hibernate.cache.use_second_level_cache", false);
sessionFactoryBean.setHibernateProperties(hibernateProperties);
- PostgreSQL版本:11.5.
- hibernate.dialect:org.hibernate.dialect.PostgreSQL9Dialect
- 休眠版本:5.4.5.Final
- PostgreSQL JDBC驱动程序:postgresql-9.4
- PostgreSQL version: 11.5.
- hibernate.dialect:org.hibernate.dialect.PostgreSQL9Dialect
- Hibernate version: 5.4.5.Final
- PostgreSQL JDBC Driver: postgresql-9.4
- 如果Hibernate认为JDBC环境支持
java.sql.Statement#getGeneratedKeys
,那么该方法将用于提取IDENTITY生成的密钥. - 否则,如果
Dialect#supportsInsertSelectIdentity
报告为true,则Hibernate将使用方言特定的INSERT + SELECT语句语法. - 否则,Hibernate将期望数据库通过某种单独的SQL命令支持某种形式的要求最近插入的IDENTITY值,如
Dialect#getIdentitySelectString
所示.
- If Hibernate believes the JDBC environment supports
java.sql.Statement#getGeneratedKeys
, then that approach will be used for extracting the IDENTITY generated keys. - Otherwise, if
Dialect#supportsInsertSelectIdentity
reports true, Hibernate will use the Dialect specific INSERT+SELECT statement syntax. - Otherwise, Hibernate will expect that the database supports some form of asking for the most recently inserted IDENTITY value via a separate SQL command as indicated by
Dialect#getIdentitySelectString
推荐答案
根据休眠
2.6.10.使用IDENTITY列
为了实现基于IDENTITY列的标识符值生成,Hibernate利用了它的 For implementing identifier value generation based on IDENTITY columns, Hibernate makes use of its
您可以通过以下方式明确指定 You can specify 您不执行此操作,因此,请以某种方式将其休眠为 You do not do it, so, hibernate somehow treat its value as 这篇关于Hibernate为什么偶尔会在持久执行select currval?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!org.hibernate.id.IdentityGenerator
id生成器,该生成器期望通过INSERT将标识符生成到表中. IdentityGenerator了解可以检索INSERT生成的值的3种不同方式:org.hibernate.id.IdentityGenerator
id generator which expects the identifier to be generated by INSERT into the table. IdentityGenerator understands 3 different ways that the INSERT-generated value might be retrieved:
java.sql.Statement#getGeneratedKeys
:java.sql.Statement#getGeneratedKeys
explicitly in the following way:<property name="hibernate.jdbc.use_get_generated_keys">true</property>
false
.然后休眠检查dialect.getIdentityColumnSupport().supportsInsertSelectIdentity()
的值.对于您的情况是false
.然后休眠进入最后一种方式.请参阅 PostgreSQL81IdentityColumnSupport 类.方法 getIdentitySelectString 生成与您抱怨的完全相同的sql.false
. Then hibernate checks value of dialect.getIdentityColumnSupport().supportsInsertSelectIdentity()
. It is false
for your case. And then hibernate follows by the last way. See the implementation of the PostgreSQL81IdentityColumnSupport class. The method getIdentitySelectString generates exactly the same sql that you complained about.