3

MS SQLServer のビューにマップする休止状態のエンティティを使用しています。ビューは、リンク サーバー上のテーブルから選択されたデータで構成されます。JPQL を使用して、このビューを正常にクエリできます。ただし、entityManager.merge(myEntity) を使用してビューを更新しようとすると、次のエラーが発生します。

com.microsoft.sqlserver.jdbc.SQLServerException: リンク サーバー "DBNAME" の OLE DB プロバイダー "MSDAORA" のネストされたトランザクションを開始できません。XACT_ABORT オプションが OFF に設定されていたため、ネストされたトランザクションが必要でした。com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError (SQLServerException.java:216) で com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult (SQLServerStatement.java:1515) で com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.doExecutePreparedStatement (SQLServerPreparedStatement.java:404) com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement$PrepStmtExecCmd.doExecute(SQLServerPreparedStatement.java:350) com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696) com. microsoft.sqlserver.jdbc.SQLServerConnection.

エラーが発生した場合に SQLServer がトランザクション全体をロールバックできるように、XACT_ABORT を ON に設定する必要があります。ネイティブ クエリを使用してこの問題を回避できましたが、理想的ではありません。

    String queryString = """set xact_abort on; update table_name set column1 = :column1, column2 = :column2 where id = :id"""
    Query query = entityManager.createNativeQuery(queryString)
    query.setParameter("column1", column1)
    query.setParameter("column2", column2)
    query.setParameter("id", id)
    query.executeUpdate()

ネイティブクエリを使用する必要がないように、マージ/永続化ごとに「set xact_abort on」を実行するように hibernate/JPA/JPAVendorAdaptor を構成する方法はありますか?

ここに私の休止状態の設定があります:

@Resource
DataSource dataSource

@Bean
JpaVendorAdapter vendorAdapter(){
    return new HibernateJpaVendorAdapter(database:Database.SQL_SERVER)
}

@Bean
AbstractEntityManagerFactoryBean entityManagerFactory(){
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(dataSource:dataSource, jpaVendorAdapter:vendorAdapter())
    em.setPackagesToScan("com.mycompany.entity")
    return em
}

@Bean
PlatformTransactionManager transactionManager() {
    return new JpaTransactionManager(entityManagerFactory:entityManagerFactory().getObject())
}
4

2 に答える 2