This is an automated email from the ASF dual-hosted git repository.

yuqi4733 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/main by this push:
     new 99b0907bf5 [#8659] fix(core): Fix parameter mismatch in 
UserRoleRelBaseSQLProvider and Test (#8702)
99b0907bf5 is described below

commit 99b0907bf5bf305d63130f7a3e0f7f3e705bd81b
Author: Samyak Jain <[email protected]>
AuthorDate: Tue Dec 2 17:08:03 2025 +0530

    [#8659] fix(core): Fix parameter mismatch in UserRoleRelBaseSQLProvider and 
Test (#8702)
    
    ### What changes were proposed in this pull request?
    
    This PR renames the `userRoleRelList` parameter to `userRoleRels` in the
    `batchInsertUserRoleRel` method of `UserRoleRelBaseSQLProvider.java`.
    This change applies to both the Java method parameter and its `@Param`
    annotation to match the collection name used within the MyBatis SQL
    template.
    
    It also adds a corresonding test to
    
`core/src/test/java/org/apache/gravitino/storage/relational/mapper/provider/base/TestUserRoleRelMapper.java`
    to prevent similar problems in the future.
    
    ### Why are the changes needed?
    
    The mismatch between the parameter name defined in the Java code
    (`userRoleRelList`) and the name expected by the SQL template
    (`userRoleRels`) would cause a runtime error when the batch insert
    operation is called.
    
    This fix resolves the bug and also makes the method signature consistent
    with other methods in the same file, such as
    `batchInsertUserRoleRelOnDuplicateKeyUpdate`.
    
    Fix: #8659
    
    ### Does this PR introduce _any_ user-facing change?
    
    No. This is an internal fix to the storage layer and does not alter any
    user-facing APIs or behavior.
    
    ### How was this patch tested?
    
    The fix was verified by running the complete test suite for the `:core`
    module. All existing tests continue to pass.
---
 .../provider/base/UserRoleRelBaseSQLProvider.java  |   4 +-
 .../provider/base/TestUserRoleRelMapper.java       | 223 +++++++++++++++++++++
 .../test/iceberg/FlinkIcebergRestCatalogIT.java    |   2 +
 3 files changed, 226 insertions(+), 3 deletions(-)

diff --git 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/UserRoleRelBaseSQLProvider.java
 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/UserRoleRelBaseSQLProvider.java
index 9e280dd7a9..3d197df540 100644
--- 
a/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/UserRoleRelBaseSQLProvider.java
+++ 
b/core/src/main/java/org/apache/gravitino/storage/relational/mapper/provider/base/UserRoleRelBaseSQLProvider.java
@@ -16,7 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-
 package org.apache.gravitino.storage.relational.mapper.provider.base;
 
 import static 
org.apache.gravitino.storage.relational.mapper.UserRoleRelMapper.USER_ROLE_RELATION_TABLE_NAME;
@@ -28,8 +27,7 @@ import org.apache.ibatis.annotations.Param;
 
 public class UserRoleRelBaseSQLProvider {
 
-  public String batchInsertUserRoleRel(
-      @Param("userRoleRelList") List<UserRoleRelPO> userRoleRelList) {
+  public String batchInsertUserRoleRel(@Param("userRoleRels") 
List<UserRoleRelPO> userRoleRels) {
     return "<script> INSERT INTO "
         + USER_ROLE_RELATION_TABLE_NAME
         + " (user_id, role_id,"
diff --git 
a/core/src/test/java/org/apache/gravitino/storage/relational/mapper/provider/base/TestUserRoleRelMapper.java
 
b/core/src/test/java/org/apache/gravitino/storage/relational/mapper/provider/base/TestUserRoleRelMapper.java
new file mode 100644
index 0000000000..38e9b044cc
--- /dev/null
+++ 
b/core/src/test/java/org/apache/gravitino/storage/relational/mapper/provider/base/TestUserRoleRelMapper.java
@@ -0,0 +1,223 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.gravitino.storage.relational.mapper.provider.base;
+
+import com.google.common.collect.Lists;
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.time.Instant;
+import java.util.List;
+import java.util.UUID;
+import org.apache.commons.io.FileUtils;
+import org.apache.gravitino.Config;
+import org.apache.gravitino.Configs;
+import org.apache.gravitino.meta.AuditInfo;
+import org.apache.gravitino.storage.relational.JDBCBackend;
+import org.apache.gravitino.storage.relational.mapper.MetalakeMetaMapper;
+import org.apache.gravitino.storage.relational.mapper.RoleMetaMapper;
+import org.apache.gravitino.storage.relational.mapper.UserMetaMapper;
+import org.apache.gravitino.storage.relational.mapper.UserRoleRelMapper;
+import org.apache.gravitino.storage.relational.po.MetalakePO;
+import org.apache.gravitino.storage.relational.po.RolePO;
+import org.apache.gravitino.storage.relational.po.UserPO;
+import org.apache.gravitino.storage.relational.po.UserRoleRelPO;
+import org.apache.gravitino.storage.relational.session.SqlSessionFactoryHelper;
+import org.apache.ibatis.session.SqlSession;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+public class TestUserRoleRelMapper {
+
+  private static final String JDBC_STORE_PATH =
+      "/tmp/gravitino_jdbc_entityStore_" + 
UUID.randomUUID().toString().replace("-", "");
+  private static final String DB_DIR = JDBC_STORE_PATH + "/testdb";
+  private static JDBCBackend backend;
+  private static UserRoleRelMapper userRoleRelMapper;
+  private static UserMetaMapper userMetaMapper;
+  private static RoleMetaMapper roleMetaMapper;
+  private static MetalakeMetaMapper metalakeMetaMapper;
+
+  @BeforeAll
+  public static void setup() throws Exception {
+    File dir = new File(DB_DIR);
+    if (dir.exists()) {
+      FileUtils.deleteDirectory(dir);
+    }
+    dir.mkdirs();
+
+    Config config = Mockito.mock(Config.class);
+    Mockito.when(config.get(Configs.ENTITY_STORE)).thenReturn("relational");
+    Mockito.when(config.get(Configs.ENTITY_RELATIONAL_STORE)).thenReturn("h2");
+    Mockito.when(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_URL))
+        
.thenReturn(String.format("jdbc:h2:file:%s;DB_CLOSE_DELAY=-1;MODE=MYSQL", 
DB_DIR));
+    
Mockito.when(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_USER)).thenReturn("gravitino");
+    Mockito.when(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_PASSWORD))
+        .thenReturn("gravitino");
+    Mockito.when(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_DRIVER))
+        .thenReturn("org.h2.Driver");
+    
Mockito.when(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_MAX_CONNECTIONS)).thenReturn(20);
+    
Mockito.when(config.get(Configs.ENTITY_RELATIONAL_JDBC_BACKEND_WAIT_MILLISECONDS))
+        .thenReturn(1000L);
+
+    backend = new JDBCBackend();
+    backend.initialize(config);
+
+    SqlSession sqlSession =
+        
SqlSessionFactoryHelper.getInstance().getSqlSessionFactory().openSession(true);
+    userRoleRelMapper = sqlSession.getMapper(UserRoleRelMapper.class);
+    userMetaMapper = sqlSession.getMapper(UserMetaMapper.class);
+    roleMetaMapper = sqlSession.getMapper(RoleMetaMapper.class);
+    metalakeMetaMapper = sqlSession.getMapper(MetalakeMetaMapper.class);
+  }
+
+  @AfterAll
+  public static void tearDown() throws IOException {
+    if (backend != null) {
+      backend.close();
+    }
+    File dir = new File(JDBC_STORE_PATH);
+    if (dir.exists()) {
+      FileUtils.deleteDirectory(dir);
+    }
+  }
+
+  @BeforeEach
+  public void init() {
+    try (SqlSession sqlSession =
+        
SqlSessionFactoryHelper.getInstance().getSqlSessionFactory().openSession(true)) 
{
+      try (Connection connection = sqlSession.getConnection()) {
+        try (Statement statement = connection.createStatement()) {
+          statement.execute("TRUNCATE TABLE user_role_rel");
+          statement.execute("TRUNCATE TABLE user_meta");
+          statement.execute("TRUNCATE TABLE role_meta");
+          statement.execute("TRUNCATE TABLE metalake_meta");
+        }
+      }
+    } catch (SQLException e) {
+      throw new RuntimeException("Truncate table failed", e);
+    }
+  }
+
+  private int countUserRoleRelsByUserId(Long userId) {
+    try (SqlSession sqlSession =
+        
SqlSessionFactoryHelper.getInstance().getSqlSessionFactory().openSession(true)) 
{
+      try (Connection connection = sqlSession.getConnection()) {
+        String query = "SELECT count(*) FROM user_role_rel WHERE user_id = ?";
+        try (PreparedStatement statement = connection.prepareStatement(query)) 
{
+          statement.setLong(1, userId);
+          try (ResultSet rs = statement.executeQuery()) {
+            if (rs.next()) {
+              return rs.getInt(1);
+            }
+            return 0;
+          }
+        }
+      }
+    } catch (SQLException e) {
+      throw new RuntimeException("SQL execution failed", e);
+    }
+  }
+
+  @Test
+  void testBatchInsertUserRoleRel() {
+    AuditInfo auditInfo =
+        
AuditInfo.builder().withCreator("test").withCreateTime(Instant.now()).build();
+
+    MetalakePO metalakePO =
+        MetalakePO.builder()
+            .withMetalakeId(1L)
+            .withMetalakeName("test_metalake")
+            .withAuditInfo(auditInfo.toString())
+            .withSchemaVersion("1.0")
+            .withCurrentVersion(1L)
+            .withLastVersion(0L)
+            .withDeletedAt(0L)
+            .build();
+    metalakeMetaMapper.insertMetalakeMeta(metalakePO);
+
+    UserPO userPO1 =
+        UserPO.builder()
+            .withUserId(1L)
+            .withUserName("user1")
+            .withMetalakeId(1L)
+            .withAuditInfo(auditInfo.toString())
+            .withCurrentVersion(1L)
+            .withLastVersion(0L)
+            .withDeletedAt(0L)
+            .build();
+    userMetaMapper.insertUserMeta(userPO1);
+
+    RolePO rolePO1 =
+        RolePO.builder()
+            .withRoleId(1L)
+            .withRoleName("role1")
+            .withMetalakeId(1L)
+            .withAuditInfo(auditInfo.toString())
+            .withCurrentVersion(1L)
+            .withLastVersion(0L)
+            .withDeletedAt(0L)
+            .build();
+    RolePO rolePO2 =
+        RolePO.builder()
+            .withRoleId(2L)
+            .withRoleName("role2")
+            .withMetalakeId(1L)
+            .withAuditInfo(auditInfo.toString())
+            .withCurrentVersion(1L)
+            .withLastVersion(0L)
+            .withDeletedAt(0L)
+            .build();
+    roleMetaMapper.insertRoleMeta(rolePO1);
+    roleMetaMapper.insertRoleMeta(rolePO2);
+
+    UserRoleRelPO userRoleRel1 =
+        UserRoleRelPO.builder()
+            .withUserId(userPO1.getUserId())
+            .withRoleId(rolePO1.getRoleId())
+            .withAuditInfo(auditInfo.toString())
+            .withCurrentVersion(1L)
+            .withLastVersion(0L)
+            .withDeletedAt(0L)
+            .build();
+    UserRoleRelPO userRoleRel2 =
+        UserRoleRelPO.builder()
+            .withUserId(userPO1.getUserId())
+            .withRoleId(rolePO2.getRoleId())
+            .withAuditInfo(auditInfo.toString())
+            .withCurrentVersion(1L)
+            .withLastVersion(0L)
+            .withDeletedAt(0L)
+            .build();
+    List<UserRoleRelPO> userRoleRels = Lists.newArrayList(userRoleRel1, 
userRoleRel2);
+
+    userRoleRelMapper.batchInsertUserRoleRel(userRoleRels);
+
+    Assertions.assertEquals(2, countUserRoleRelsByUserId(userPO1.getUserId()));
+  }
+}
diff --git 
a/flink-connector/flink/src/test/java/org/apache/gravitino/flink/connector/integration/test/iceberg/FlinkIcebergRestCatalogIT.java
 
b/flink-connector/flink/src/test/java/org/apache/gravitino/flink/connector/integration/test/iceberg/FlinkIcebergRestCatalogIT.java
index da6a230937..79b3e4cc28 100644
--- 
a/flink-connector/flink/src/test/java/org/apache/gravitino/flink/connector/integration/test/iceberg/FlinkIcebergRestCatalogIT.java
+++ 
b/flink-connector/flink/src/test/java/org/apache/gravitino/flink/connector/integration/test/iceberg/FlinkIcebergRestCatalogIT.java
@@ -28,6 +28,7 @@ import 
org.apache.gravitino.flink.connector.iceberg.IcebergPropertiesConstants;
 import org.apache.gravitino.flink.connector.integration.test.utils.TestUtils;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.condition.DisabledIf;
 
 @Tag("gravitino-docker-test")
@@ -48,6 +49,7 @@ public class FlinkIcebergRestCatalogIT extends 
FlinkIcebergCatalogIT {
   }
 
   @Override
+  @Test
   public void testListSchema() {
     doWithCatalog(
         currentCatalog(),

Reply via email to