当前位置: 首页 > 知识库问答 >
问题:

MS SQL Server 2008 R2标识列的JPA批注

夏才
2023-03-14

我想知道正确的JPA注释设置来处理MS Server2008 R2标识列。

MS Server 2008 R2(RTM)不支持序列,但当我使用原始SQL测试时,标识会自动递增。

但是,在JPA中,我不能通过任何策略(IDENTITY、AUTO、TABLE)在@generatedvalue注释上使其工作,而且我不允许更改DB模式,因为它是其他的。我没有尝试用顺序,因为没有顺序。

CREATE TABLE [dbo].[invoice_header](
    [invoice_id] [int] IDENTITY(1,1) NOT NULL,
    [ApprovalDate] [datetime] NULL,
    [ApproverUserName] [nvarchar](50) NULL,
 CONSTRAINT [PK_invoice_header] PRIMARY KEY CLUSTERED 
(
    [invoice_id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
@Entity
@Table(name = "invoice_header")
public class InvoiceHeader {

    @Id
    @GeneratedValue( strategy = GenerationType.IDENTITY )
    @Column(name="invoice_id")
    private Long invoiceId;
Hibernate: insert into tbl_acct_textura_invoice_header (invoice_id, ApprovalDate, ApproverUserName) values (null, ?, ?)
2015-06-16 11:12:24.149 ERROR 7157 --- [tp1024240671-18] o.h.engine.jdbc.spi.SqlExceptionHelper   : DEFAULT or NULL are not allowed as explicit identity values.

由于在ID上传递null,它失败了。我可以在@column注释上通过insertable=false和updatable=false进行insert时使HQL不包含invoice_id列,但是hibernate不喜欢不包含Id列,如下所示。有什么建议吗?另外,我使用的是spring-data JpaRepository

插入期间不包括id列时出现Hibernate错误

nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): ...InvoiceHeader

共有1个答案

应和光
2023-03-14

我刚刚发现我没有在LocalContainerEntityManagerFactoryBean上设置hibernate方言。在将org.hibernate.dialt.SQLServer2008Dialction设置为Hibernate方言之后,GenerationType.Identity就像Neil提到的那样工作得很好。

下面是我的spring数据配置和application.properties。我有多个数据源,一个是H2嵌入式数据源供内部使用,另一个是MS SQL2008服务器供远程数据访问,这是我发布的。

MS SQL 2008 server的Spring数据配置

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "adapterEntityManagerFactory",
        transactionManagerRef = "adapterTransactionManager",
        basePackages = {"com.textura.client.erp.database.repository"})
public class ErpRepositoryConfig {
    @Autowired
    JpaVendorAdapter jpaVendorAdapter;

    @Value("${adapter.datasource.url}")
    private String databaseUrl;

    @Value("${adapter.datasource.username}")
    private String username;

    @Value("${adapter.datasource.password}")
    private String password;

    @Value("${adapter.datasource.hibernate.dialect}")
    private String dialect;

    public DataSource dataSource() {
        return new DriverManagerDataSource(databaseUrl, username, password);
    }
    @Bean(name = "adapterEntityManager")
    public EntityManager entityManager() {
        return entityManagerFactory().createEntityManager();
    }

    @Bean(name = "adapterEntityManagerFactory")
    public EntityManagerFactory entityManagerFactory() {
        Properties properties = new Properties();
        properties.setProperty("hibernate.dialect", dialect);  //"org.hibernate.dialect.SQLServer2008Dialect"
        LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
        lef.setDataSource(dataSource());
        lef.setJpaVendorAdapter(jpaVendorAdapter);
        lef.setPackagesToScan("com.textura.client.erp.database.model");
        lef.setPersistenceUnitName("adapterPersistenceUnit");
        lef.setJpaProperties(properties);
        lef.afterPropertiesSet();
        return lef.getObject();
    }

    @Bean(name = "adapterTransactionManager")
    public PlatformTransactionManager transactionManager() {
        return new JpaTransactionManager(entityManagerFactory());
    }
}
# database configuration
spring.datasource.url=jdbc:h2:file:~/internal;AUTO_SERVER=TRUE
spring.datasource.username=sa
spring.datasource.password=
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.schema=schema.sql
spring.datasource.data=data.sql
spring.datasource.initialize=false
#spring.datasource.initialize=true only for first time to create table, after that switch to false

# JPA. Hibernate
spring.jpa.database=H2
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create-drop
#spring.jpa.hibernate.ddl-auto=choose one of [create-drop, create, update, validate, none]
spring.jpa.hibernate.naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.show-sql=true
spring.data.jpa.repositories.enabled=true


# MS SQL Server 2008 datasource
adapter.datasource.url=jdbc:sqlserver://some.ip.address:1433;databaseName=Remote
adapter.datasource.username=sa
adapter.datasource.password=password
adapter.datasource.hibernate.dialect=org.hibernate.dialect.SQLServer2008Dialect
Hibernate: insert into invoice_header (ApprovalDate, ApproverUserName) values (?, ?)
 类似资料:
  • 问题内容: JPA 2.0(Hibernate 4.2.4.Final/Spring 3.2.8.Release)/ Mysql 5.6 对于管理实体E w /自动生成的主键,例如 出于传统原因,foo需要等于:{id}:。例如,如果id为204,则foo将为“:204:”,因此在事务中发生这种情况是可行的 有没有一种更好的方法来计算值取决于生成的ID的派生列?没有上述技巧,即在持久化之后直接更新

  • 我有一个实体,除了主键之外,还应该为它生成一个额外的唯一标识符: 属性值通过调用 并添加前缀字符串,从 postgres 序列值派生而来。当我执行大容量插入时,我必须求助于在我的JPA存储库中为实体定义的自定义查询,该查询一次检索多个序列值,但我想使此过程自动进行。 我尝试实现< code>IdentifierGenerator接口,但我能实现的最好结果是为每个插入的新实体执行一个< code>S

  • 我正在尝试批量插入到具有标识列的表中。但我的主机文件包含标识列的空值。当我发出“bcp”命令时,我得到一个错误- 正在开始复制。。。 SQLState=S1000,NativeError=0 错误=[Microsoft][SQL服务器本地客户端10.0]在BCP数据文件中遇到意外的EOF SQLState=23000,NativeError=515 错误=[Microsoft][SQL Serve

  • 问题是,我可以强制在末尾填充缺少的ID吗?

  • 如何更改身份栏? 例如,我有一张表: 我需要随着时间的推移而改变

  • 我有以下hsqldb数据库: 我需要添加条目,只有当它们在表中不存在时。我希望在一个步骤中完成这项工作(而不是通过选择步骤来确定条目是否在表中,如果不是这样,则通过第二个步骤插入) hsqldb对此具有合并操作。然而,问题是我有一个id-IDENTITY列,hsqldb应该自动负责设置值,我不知道如何告诉合并操作。 这可以工作,但我必须给出id(3),我需要由hsqldb自动设置id(就像上面的插