test: Add unit and integration tests for callableStatement and current timestamp support in OpenGaussDialect

This commit is contained in:
SolisAmicus 2024-09-22 23:36:46 +08:00
parent 0981ea829b
commit 8f95aa5bec
14 changed files with 279 additions and 24 deletions

View File

@ -0,0 +1,21 @@
package org.hibernate.dialect.entity.callablestatement;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "test_callable_statement_table")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TestEntity {
@Id
private Long id;
private String name;
}

View File

@ -0,0 +1,85 @@
package org.hibernate.dialect.integration;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.dialect.entity.callablestatement.TestEntity;
import org.hibernate.dialect.util.HibernateUtil;
import org.junit.jupiter.api.*;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;
public class OpenGaussCallableStatementIntegrationTest {
private static SessionFactory sessionFactory;
@BeforeAll
public static void init() {
/**
* OpenGauss 函数和存储过程示例
*
* 函数
*
* CREATE OR REPLACE FUNCTION get_users()
* RETURNS refcursor AS
* $$
* DECLARE
* out_cursor refcursor;
* BEGIN
* OPEN out_cursor FOR SELECT id, name FROM test_table;
* RETURN out_cursor;
* END;
* $$ LANGUAGE plpgsql;
*
* 存储过程
*
* CREATE OR REPLACE PROCEDURE get_users(out_cursor OUT REFCURSOR)
* AS
* BEGIN
* OPEN out_cursor FOR SELECT id, name FROM users ORDER BY id;
* END;
*/
sessionFactory = HibernateUtil.getSessionFactory(TestEntity.class);
Session session = sessionFactory.openSession();
session.beginTransaction();
session.createNativeQuery("DELETE FROM test_table").executeUpdate();
session.save(new TestEntity(1L, "Alice"));
session.save(new TestEntity(2L, "Bob"));
session.save(new TestEntity(3L, "Charlie"));
session.getTransaction().commit();
session.close();
}
@AfterAll
public static void tearDownAll() {
if (sessionFactory != null) {
sessionFactory.close();
}
}
@Test
public void testCallableStatement() throws Exception {
Session session = sessionFactory.openSession();
Connection connection = session.doReturningWork(conn -> conn);
String functionCall = "{? = call get_users()}";
CallableStatement callableStatement = connection.prepareCall(functionCall);
callableStatement.registerOutParameter(1, Types.REF_CURSOR);
callableStatement.execute();
ResultSet resultSet = (ResultSet) callableStatement.getObject(1);
List<TestEntity> testEntities = new ArrayList<>();
while (resultSet.next()) {
Long id = resultSet.getLong("id");
String name = resultSet.getString("name");
testEntities.add(new TestEntity(id, name));
}
Assertions.assertEquals(3, testEntities.size(), "应检索到 3 个用户");
Assertions.assertEquals("Alice", testEntities.get(0).getName());
Assertions.assertEquals("Bob", testEntities.get(1).getName());
Assertions.assertEquals("Charlie", testEntities.get(2).getName());
resultSet.close();
callableStatement.close();
}
}

View File

@ -6,8 +6,6 @@ import org.hibernate.dialect.entity.ddl.AnnotatedEntity;
import org.hibernate.dialect.util.HibernateUtil;
import org.junit.jupiter.api.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class OpenGaussDialectDDLCommentTest {
private static SessionFactory sessionFactory;
@ -38,10 +36,10 @@ public class OpenGaussDialectDDLCommentTest {
session.getTransaction().commit();
String tableCommentQuery = "SELECT description " + "FROM pg_description " + "WHERE objoid = (" + " SELECT oid FROM pg_class WHERE relname = 'annotated_table'" + ") AND objsubid = 0";
String tableComment = (String) session.createNativeQuery(tableCommentQuery).getSingleResult();
assertEquals("This is a table comment", tableComment);
Assertions.assertEquals("This is a table comment", tableComment);
String columnCommentQuery = "SELECT description " + "FROM pg_description " + "WHERE objoid = (" + " SELECT oid FROM pg_class WHERE relname = 'annotated_table'" + ") AND objsubid = (" + " SELECT attnum FROM pg_attribute " + " WHERE attrelid = (" + " SELECT oid FROM pg_class WHERE relname = 'annotated_table'" + " ) AND attname = 'annotated_column'" + ")";
String columnComment = (String) session.createNativeQuery(columnCommentQuery).getSingleResult();
assertEquals("This is a column comment", columnComment);
Assertions.assertEquals("This is a column comment", columnComment);
session.close();
}
}

View File

@ -8,12 +8,10 @@ import org.hibernate.dialect.entity.ddl.ParentEntity;
import org.hibernate.dialect.util.HibernateUtil;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class OpenGaussDialectDDLConstraintTest {
private static SessionFactory sessionFactory;
@ -49,7 +47,7 @@ public class OpenGaussDialectDDLConstraintTest {
session.beginTransaction();
String sql = "SELECT constraint_name FROM information_schema.table_constraints WHERE table_name='child_table' AND constraint_type='FOREIGN KEY'";
String constraintName = (String) session.createNativeQuery(sql).uniqueResult();
assertEquals("fk_child_parent", constraintName);
Assertions.assertEquals("fk_child_parent", constraintName);
session.getTransaction().commit();
session.close();
}
@ -70,7 +68,7 @@ public class OpenGaussDialectDDLConstraintTest {
session.getTransaction().commit();
session.beginTransaction();
Long childCount = (Long) session.createQuery("SELECT COUNT(c) FROM ChildEntity c").uniqueResult();
assertEquals(Long.valueOf(0), childCount);
Assertions.assertEquals(Long.valueOf(0), childCount);
session.getTransaction().commit();
session.close();
}
@ -98,7 +96,7 @@ public class OpenGaussDialectDDLConstraintTest {
session.beginTransaction();
String checkConstraintSQL = "SELECT constraint_name FROM information_schema.table_constraints WHERE table_name='child_table' AND constraint_name='test_constraint'";
Object result = session.createNativeQuery(checkConstraintSQL).uniqueResult();
assertNull(result);
Assertions.assertNull(result);
session.getTransaction().commit();
session.close();
}

View File

@ -13,6 +13,7 @@ import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
import org.hibernate.tool.schema.TargetType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import javax.persistence.Entity;
@ -20,12 +21,12 @@ import javax.persistence.Id;
import javax.persistence.Table;
import java.util.EnumSet;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
public class OpenGaussDialectDDLTableAndColumTest {
private static StandardServiceRegistry standardRegistry;
private static Metadata metadata;
private static SessionFactory sessionFactory;
public static void setUp(Class<?>... testClasses) {
@ -73,7 +74,7 @@ public class OpenGaussDialectDDLTableAndColumTest {
Session session = sessionFactory.openSession();
String sql = "SELECT table_name FROM information_schema.tables WHERE table_name = 'test_table'";
String tableName = (String) session.createNativeQuery(sql).uniqueResult();
assertEquals("test_table", tableName);
Assertions.assertEquals("test_table", tableName);
session.close();
}
@ -101,7 +102,7 @@ public class OpenGaussDialectDDLTableAndColumTest {
Session session = sessionFactory.openSession();
String sql = "SELECT column_name FROM information_schema.columns WHERE table_name = 'test_table' AND column_name = 'description'";
String columnName = (String) session.createNativeQuery(sql).uniqueResult();
assertEquals("description", columnName);
Assertions.assertEquals("description", columnName);
session.close();
}
@ -113,7 +114,7 @@ public class OpenGaussDialectDDLTableAndColumTest {
Session session = sessionFactory.openSession();
String sql = "SELECT table_name FROM information_schema.tables WHERE table_name = 'test_table'";
String tableName = (String) session.createNativeQuery(sql).uniqueResult();
assertNull(tableName);
Assertions.assertNull(tableName);
session.close();
}
}

View File

@ -22,7 +22,7 @@ public class OpenGaussFunctionTest {
private Session session;
@BeforeAll
public static void setUpAll() {
public static void init() {
sessionFactory = HibernateUtil.getSessionFactory(TestEntity.class);
}
@ -42,7 +42,7 @@ public class OpenGaussFunctionTest {
}
@AfterAll
public static void tearDownALL() {
public static void close() {
if (sessionFactory != null) {
sessionFactory.close();
}

View File

@ -3,6 +3,7 @@ package org.hibernate.dialect.integration;
import org.hibernate.*;
import org.hibernate.dialect.entity.lock.TestEntity;
import org.hibernate.dialect.util.HibernateUtil;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@ -33,6 +34,12 @@ public class OpenGaussLockIntegrationTest {
session.close();
}
@AfterAll
public static void close() {
if (sessionFactory != null) {
sessionFactory.close();
}
}
// testPessimisticWriteLockNoWait()测试当记录已被锁定且设置不等待时事务是否会立即失败确保数据一致性和锁机制的有效性
@Test
public void testPessimisticWriteLockNoWait() {

View File

@ -0,0 +1,65 @@
package org.hibernate.dialect.unit;
import org.hibernate.dialect.OpenGaussDialect;
import org.junit.jupiter.api.*;
import java.sql.CallableStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
public class OpenGaussDialectCallableStatementTest {
private static OpenGaussDialect dialect;
private CallableStatement callableStatement;
@BeforeAll
public static void init() {
dialect = new OpenGaussDialect();
}
@BeforeEach
public void setup() {
callableStatement = mock(CallableStatement.class);
}
@AfterEach
public void teardown() {
callableStatement = null;
}
@Test
public void testRegisterResultSetOutParameter() throws SQLException {
int position = 1;
int returnedPosition = dialect.registerResultSetOutParameter(callableStatement, position);
verify(callableStatement).registerOutParameter(position, Types.REF_CURSOR);
Assertions.assertEquals(position + 1, returnedPosition, "Position should be incremented by 1");
}
@Test
public void testGetResultSet() throws SQLException {
ResultSet mockResultSet = mock(ResultSet.class);
when(callableStatement.getObject(1)).thenReturn(mockResultSet);
ResultSet resultSet = dialect.getResultSet(callableStatement);
verify(callableStatement).execute();
verify(callableStatement).getObject(1);
Assertions.assertEquals(mockResultSet, resultSet, "ResultSet should match the one returned by getObject(1)");
}
@Test
public void testGetResultSetWithPosition() throws SQLException {
ResultSet mockResultSet = mock(ResultSet.class);
when(callableStatement.getObject(1)).thenReturn(mockResultSet);
ResultSet resultSet = dialect.getResultSet(callableStatement, 1);
verify(callableStatement).getObject(1);
Assertions.assertEquals(mockResultSet, resultSet, "ResultSet should match the one returned by getObject(1)");
RuntimeException runtimeException = assertThrows(UnsupportedOperationException.class, () -> {
dialect.getResultSet(callableStatement, 2);
});
Assertions.assertTrue(runtimeException.getMessage().contains("OpenGauss only supports REF_CURSOR parameters as the first parameter"));
}
}

View File

@ -0,0 +1,80 @@
package org.hibernate.dialect.unit;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.dialect.OpenGaussDialect;
import org.hibernate.dialect.util.HibernateUtil;
import org.junit.jupiter.api.*;
import javax.persistence.*;
import java.sql.Timestamp;
public class OpenGaussDialectCurrentTimestampTest {
@Entity
@Table(name = "test_entity")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TestEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Version
private Timestamp version;
}
private static SessionFactory sessionFactory;
@BeforeAll
public static void init() {
sessionFactory = HibernateUtil.getSessionFactory(TestEntity.class);
}
@AfterAll
public static void close() {
if (sessionFactory != null) {
sessionFactory.close();
}
}
@Test
public void testCurrentTimestampSelection() {
Session session = sessionFactory.openSession();
session.beginTransaction();
OpenGaussDialect dialect = new OpenGaussDialect();
String sql = dialect.getCurrentTimestampSelectString();
Timestamp currentTimestamp = (Timestamp) session.createNativeQuery(sql).getSingleResult();
System.out.println("从数据库获取的当前时间戳: " + currentTimestamp);
Timestamp systemTimestamp = new Timestamp(System.currentTimeMillis());
System.out.println("从系统获取的当前时间戳: " + systemTimestamp);
long difference = Math.abs(systemTimestamp.getTime() - currentTimestamp.getTime());
Assertions.assertTrue(difference < 10000, "时间戳差异应小于 1 秒");
session.getTransaction().commit();
}
@Test
public void testVersioning() {
Session session = sessionFactory.openSession();
session.beginTransaction();
TestEntity entity = new TestEntity();
entity.setName("测试名称");
session.save(entity);
session.getTransaction().commit();
System.out.println("初始版本(时间戳): " + entity.getVersion());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
session.beginTransaction();
entity.setName("更新后的名称");
session.update(entity);
session.getTransaction().commit();
System.out.println("更新后的版本(时间戳): " + entity.getVersion());
Assertions.assertNotNull(entity.getVersion());
}
}

View File

@ -10,11 +10,11 @@ import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class OpenGaussDialectDDLIntegrationTest {
public class OpenGaussDialectDDLTest {
private static OpenGaussDialect dialect;
@BeforeAll
public static void setUp() {
public static void init() {
dialect = new OpenGaussDialect();
}

View File

@ -12,7 +12,7 @@ public class OpenGaussDialectLimitHandlerTest {
private static OpenGaussDialect dialect;
@BeforeAll
public static void setUp() {
public static void init() {
dialect = new OpenGaussDialect();
}

View File

@ -11,7 +11,7 @@ public class OpenGaussDialectLockTest {
private static OpenGaussDialect dialect;
@BeforeAll
public static void setUp() {
public static void init() {
dialect = new OpenGaussDialect();
}

View File

@ -12,7 +12,7 @@ public class OpenGaussDialectSequenceTest {
private static OpenGaussDialect dialect;
@BeforeAll
public static void setUp() {
public static void init() {
dialect = new OpenGaussDialect();
}

View File

@ -14,7 +14,7 @@ public class OpenGaussIdentityColumnSupportTest {
private static OpenGaussDialect dialect;
@BeforeAll
public static void setUp() {
public static void init() {
dialect = new OpenGaussDialect();
}