mirror of
https://gitee.com/pnoker/iot-dc3.git
synced 2026-09-19 10:11:36 +08:00
fix(manager): drop invalid affectData attribute from mapper inserts
affectData is not declared for insert by the MyBatis mapper DTD, so the attribute only surfaces as a startup error after the affected module deploys. Remove it from every upsertLeaseState variant and document that the atomically advanced assignment version is re-selected in the same transaction rather than returned. Add ManagerMapperXmlGrammarTest to parse every mapping/*.xml against the bundled DTD so future invalid attributes fail the build instead of application startup. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+2
-1
@@ -79,7 +79,8 @@ public interface DriverLeaseMapper {
|
||||
@Param("driverId") Long driverId);
|
||||
|
||||
/**
|
||||
* Upserts reconciliation state and returns the atomically advanced assignment version.
|
||||
* Upserts reconciliation state. The atomically advanced assignment version is not part of the return value;
|
||||
* callers re-select it inside the same transaction, so the affected-row count carries no lease semantics.
|
||||
*/
|
||||
int upsertLeaseState(@Param("tenantId") Long tenantId,
|
||||
@Param("driverId") Long driverId,
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
No RETURNING: the manager re-selects in the same transaction (MySQL
|
||||
has no INSERT ... RETURNING).
|
||||
-->
|
||||
<insert id="upsertLeaseState" affectData="true" flushCache="true">
|
||||
<insert id="upsertLeaseState" flushCache="true">
|
||||
INSERT INTO dc3_driver_lease_state
|
||||
(tenant_id, driver_id, membership_hash, device_revision)
|
||||
VALUES (#{tenantId}, #{driverId}, #{membershipHash}, #{deviceRevision})
|
||||
@@ -137,7 +137,7 @@
|
||||
operate_time = CURRENT_TIMESTAMP
|
||||
</insert>
|
||||
|
||||
<insert id="upsertLeaseState" databaseId="mysql" affectData="true" flushCache="true">
|
||||
<insert id="upsertLeaseState" databaseId="mysql" flushCache="true">
|
||||
INSERT INTO dc3_driver_lease_state
|
||||
(tenant_id, driver_id, membership_hash, device_revision)
|
||||
VALUES (#{tenantId}, #{driverId}, #{membershipHash}, #{deviceRevision}) AS new
|
||||
@@ -149,7 +149,7 @@
|
||||
|
||||
<!-- MariaDB twin of the mysql fork above: identical shape, but
|
||||
MariaDB never adopted the AS-new row alias: VALUES(col) instead. -->
|
||||
<insert id="upsertLeaseState" databaseId="mariadb" affectData="true" flushCache="true">
|
||||
<insert id="upsertLeaseState" databaseId="mariadb" flushCache="true">
|
||||
INSERT INTO dc3_driver_lease_state
|
||||
(tenant_id, driver_id, membership_hash, device_revision)
|
||||
VALUES (#{tenantId}, #{driverId}, #{membershipHash}, #{deviceRevision})
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2016-present the IoT DC3 original author or authors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package io.github.pnoker.common.manager.scan;
|
||||
|
||||
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
|
||||
import org.apache.ibatis.session.Configuration;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Grammar gate for mapper XML: every mapping file on the classpath must parse
|
||||
* against the MyBatis mapper DTD. Attributes the bundled DTD does not declare
|
||||
* for an element (for example {@code affectData} on {@code insert}) otherwise
|
||||
* surface only at application startup, so this gate fails the build instead.
|
||||
* No database is involved — parsing alone exercises the DTD validation that
|
||||
* {@code sqlSessionFactory} performs.
|
||||
*/
|
||||
class ManagerMapperXmlGrammarTest {
|
||||
|
||||
@Test
|
||||
void allMappingXmlParsesAgainstTheMybatisDtd() throws Exception {
|
||||
Resource[] resources = new PathMatchingResourcePatternResolver()
|
||||
.getResources("classpath*:mapping/*.xml");
|
||||
assertThat(resources).isNotEmpty();
|
||||
for (Resource resource : resources) {
|
||||
Configuration configuration = new Configuration();
|
||||
try (InputStream in = resource.getInputStream()) {
|
||||
new XMLMapperBuilder(in, configuration, resource.getDescription(), configuration.getSqlFragments()).parse();
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("mapper XML rejected by MyBatis: " + resource.getDescription(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user