JPA 禁止执行 ALTER SEQUENCE

Posted

技术标签:

【中文标题】JPA 禁止执行 ALTER SEQUENCE【英文标题】:JPA disable execution of ALTER SEQUENCE 【发布时间】:2020-03-14 03:01:28 【问题描述】:

我有一个带有 Spring Boot 应用程序的 Spring Batch 和一个 Oracle Wallet 来连接和打开 JPA 来处理持久性。我有一些实体,它们的主键是用数据库中的序列管理的,比如这个:

CREATED 11/11/11
LAST_DDL_TIME   11/11/11
SEQUENCE_OWNER  EXAMPLE
SEQUENCE_NAME   EXAMPLE_SEQ
MIN_VALUE   1
MAX_VALUE   9999999999999999999999999999
INCREMENT_BY    1
CYCLE_FLAG  N
ORDER_FLAG  N
CACHE_SIZE  20
LAST_NUMBER 1111

以及对应的实体注解:

@Id 
@SequenceGenerator(name="seq_examples", sequenceName="EXAMPLE_SEQ", allocationSize = 1)  
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="seq_examples")
@Column (name="ID_EXAMPLE", nullable=false)
private Integer id_example;

使用这段代码,JPA 不断尝试执行 ALTER SEQUENCE,阅读了很多关于此的内容,我有两种解决问题的方法,使用 Spring Boot 配置文件或使用 persistence.xml 配置文件。

我都试过了:config ->

@配置 公共类 ContextConfiguration

    @Bean(name="springtest_entitymanager")
    public LocalContainerEntityManagerFactoryBean getEntityManagerFactoryBean(
    @Qualifier("vendorAdapter") JpaVendorAdapter jpaVendorAdapter, 
    @Value("$$enviroment.databaseSchema") String databaseSchema,
    @Qualifier("datasourceWalletExampleDB") DataSource dataSource,
    //@Value("$ConnectionFactoryProperties") String ConnectionFactoryProperties,
    @Value("$$enviroment.openjpa.ConnectionFactoryProperties") String 
ConnectionFactoryProperties,
    @Value("$$enviroment.openjpa.log") String logLevel
    )

Map<String, String> jpaProperties = new HashMap<String, String>();
jpaProperties.put("openjpa.jdbc.Schema", databaseSchema);
jpaProperties.put("openjpa.Log", logLevel); 
jpaProperties.put("openjpa.ConnectionFactoryProperties", ConnectionFactoryProperties);

jpaProperties.put("openjpa.jdbc.DBDictionary.disableAlterSequenceIncrementBy", "true");

//debug only
//jpaProperties.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");

LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new 
LocalContainerEntityManagerFactoryBean();
localContainerEntityManagerFactoryBean.setPersistenceUnitName("pu_Example");
localContainerEntityManagerFactoryBean.setDataSource(dataSource);
localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter);
localContainerEntityManagerFactoryBean.setJpaPropertyMap(jpaProperties);
return localContainerEntityManagerFactoryBean;

...

和持久性 ->

<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>

<class>exampleapp.dao.model.Example</class>


<properties>
    <property name="openjpa.Log" value="DefaultLevel=ERROR" />
    <property name="openjpa.ConnectionFactoryProperties" value="PrettyPrint=true, 
PrettyPrintLineLength=72" />
    <property name="openjpa.jdbc.Schema" value="EXAMPLE" />
    <property name="openjpa.jdbc.DBDictionary" value="DisableAlterSeqenceIncrementBy=true" />

</properties>

但它仍然在做alter sequence 语句,我还能做什么?

我已经阅读的一些信息:

https://issues.apache.org/jira/browse/OPENJPA-2450

https://www-01.ibm.com/support/docview.wss?uid=swg1PI05956

Java - JPA - Generators - @SequenceGenerator

感谢所有阅读本文的人

【问题讨论】:

你检查this recomendation了吗? 是的,我做到了,同样的结果。 【参考方案1】:

两个属性(persistence.xml / 配置类)工作正常,但我必须使用更改序列权限至少运行一次应用程序,可能某些 pk 在第一次运行时 JPA 和 DB 之间不同步,我认为是因为数据库缓存。在这种情况下,数据库是从另一个环境迁移而来的。

以alter sequence 权限运行后,权限被删除,再运行几次后,我没有看到任何问题。

我发现的有关序列缓存的有用信息以及我对其他人的帮助:

https://developer.ibm.com/answers/questions/503873/why-does-the-jpa-sequence-generator-increase-more/

http://www.dba-oracle.com/t_sequence_caching.htm

https://www.logicbig.com/tutorials/java-ee-tutorial/jpa/seq-generator.html

【讨论】:

以上是关于JPA 禁止执行 ALTER SEQUENCE的主要内容,如果未能解决你的问题,请参考以下文章

实体类禁止填充数据库

mysql 5.6 在线DDL

Netezza SQL ALTER TABLE 在存储过程中的替代方案?

如何在 Oracle 循环中的 select 语句中执行 alter 命令?

在oracle中执行alter存储过程时出现无效表名错误

执行ALTER TABLE语句时如何避免长时间阻塞并发查询