Skip to content

Commit 4f34684

Browse files
Merge remote-tracking branch 'origin/main'
2 parents 84baa9f + e6cd80f commit 4f34684

File tree

11 files changed

+100
-44
lines changed

11 files changed

+100
-44
lines changed

hibernate-dialect/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 1.3.0 ##
2+
3+
- Added support UUID YDB type
4+
15
## 1.2.0 ##
26

37
- Added custom decimal jdbc codes `DECIMAL_31_9`, `DECIMAL_35_0`, `DECIMAL_35_9`

hibernate-dialect/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>tech.ydb.dialects</groupId>
88
<artifactId>hibernate-ydb-dialect</artifactId>
9-
<version>1.2.0</version>
9+
<version>1.3.0</version>
1010

1111
<packaging>jar</packaging>
1212

hibernate-dialect/src/main/java/tech/ydb/hibernate/dialect/YdbDialect.java

+11-4
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,13 @@
4949
import static org.hibernate.type.SqlTypes.TIMESTAMP_WITH_TIMEZONE;
5050
import static org.hibernate.type.SqlTypes.TIME_WITH_TIMEZONE;
5151
import static org.hibernate.type.SqlTypes.TINYINT;
52+
import static org.hibernate.type.SqlTypes.UUID;
5253
import static org.hibernate.type.SqlTypes.VARBINARY;
5354
import static org.hibernate.type.SqlTypes.VARCHAR;
5455
import org.hibernate.type.StandardBasicTypes;
56+
import org.hibernate.type.descriptor.java.UUIDJavaType;
5557
import org.hibernate.type.descriptor.jdbc.JdbcType;
58+
import org.hibernate.type.descriptor.jdbc.UUIDJdbcType;
5659
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
5760
import org.hibernate.type.descriptor.sql.internal.DdlTypeImpl;
5861
import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry;
@@ -111,6 +114,7 @@ protected String columnType(int sqlTypeCode) {
111114
LONG32VARCHAR, LONG32NVARCHAR, LONGVARCHAR, LONGNVARCHAR -> "Text";
112115
case BINARY, VARBINARY, BLOB, LONGVARBINARY, LONG32VARBINARY -> "Bytes";
113116
case JSON -> "Json";
117+
case UUID, YdbJdbcCode.UUID -> "Uuid";
114118
default -> super.columnType(sqlTypeCode);
115119
};
116120
}
@@ -119,20 +123,22 @@ protected String columnType(int sqlTypeCode) {
119123
public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
120124
super.contributeTypes(typeContributions, serviceRegistry);
121125

126+
typeContributions.contributeJavaType(UUIDJavaType.INSTANCE);
127+
typeContributions.contributeJdbcType(UUIDJdbcType.INSTANCE);
122128
typeContributions.contributeJavaType(LocalDateTimeJavaType.INSTANCE);
123129
typeContributions.contributeJdbcType(LocalDateTimeJdbcType.INSTANCE);
124130
typeContributions.contributeJavaType(LocalDateJavaType.INSTANCE);
125131
typeContributions.contributeJdbcType(LocalDateJdbcType.INSTANCE);
126132
typeContributions.contributeJavaType(InstantJavaType.INSTANCE);
127133
typeContributions.contributeJdbcType(InstantJdbcType.INSTANCE);
128-
typeContributions.contributeJdbcType(new DecimalJdbcType(YdbJdbcCode.DECIMAL_22_9));
129-
typeContributions.contributeJdbcType(new DecimalJdbcType(YdbJdbcCode.DECIMAL_31_9));
130-
typeContributions.contributeJdbcType(new DecimalJdbcType(YdbJdbcCode.DECIMAL_35_0));
131-
typeContributions.contributeJdbcType(new DecimalJdbcType(YdbJdbcCode.DECIMAL_35_9));
132134

133135
// custom jdbc codec
134136
typeContributions.contributeJdbcType(Uint8JdbcType.INSTANCE);
135137
typeContributions.contributeJavaType(BigDecimalJavaType.INSTANCE_22_9);
138+
typeContributions.contributeJdbcType(new DecimalJdbcType(YdbJdbcCode.DECIMAL_22_9));
139+
typeContributions.contributeJdbcType(new DecimalJdbcType(YdbJdbcCode.DECIMAL_31_9));
140+
typeContributions.contributeJdbcType(new DecimalJdbcType(YdbJdbcCode.DECIMAL_35_0));
141+
typeContributions.contributeJdbcType(new DecimalJdbcType(YdbJdbcCode.DECIMAL_35_9));
136142
}
137143

138144
@Override
@@ -141,6 +147,7 @@ protected void registerColumnTypes(TypeContributions typeContributions, ServiceR
141147

142148
final DdlTypeRegistry ddlTypeRegistry = typeContributions.getTypeConfiguration().getDdlTypeRegistry();
143149

150+
ddlTypeRegistry.addDescriptor(new DdlTypeImpl(UUID, "Uuid", "Uuid", this));
144151
ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.DATETIME, "Datetime", "Datetime", this));
145152
ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.UINT8, "Uint8", "Uint8", this));
146153
ddlTypeRegistry.addDescriptor(new DdlTypeImpl(YdbJdbcCode.DECIMAL_22_9, "Decimal(22, 9)", "Decimal(22, 9)", this));

hibernate-dialect/src/test/java/tech/ydb/hibernate/types/Employee.java

+3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.math.BigDecimal;
1010
import java.time.LocalDate;
1111
import java.time.LocalDateTime;
12+
import java.util.UUID;
1213
import lombok.AllArgsConstructor;
1314
import lombok.Data;
1415
import lombok.NoArgsConstructor;
@@ -59,6 +60,8 @@ public class Employee {
5960
@Enumerated(EnumType.STRING)
6061
private Enum bnEnum;
6162

63+
private UUID uuid;
64+
6265
public enum Enum {
6366
ONE, TWO
6467
}

hibernate-dialect/src/test/java/tech/ydb/hibernate/types/TypesTest.java

+22-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.math.BigDecimal;
44
import java.time.LocalDate;
55
import java.time.LocalDateTime;
6+
import java.util.List;
7+
import java.util.UUID;
68
import org.hibernate.cfg.AvailableSettings;
79
import static org.junit.jupiter.api.Assertions.assertEquals;
810
import org.junit.jupiter.api.BeforeAll;
@@ -26,7 +28,7 @@ public class TypesTest {
2628
static void beforeAll() {
2729
TestUtils.SESSION_FACTORY = basedConfiguration()
2830
.addAnnotatedClass(Employee.class)
29-
.setProperty(AvailableSettings.URL, jdbcUrl(ydb))
31+
.setProperty(AvailableSettings.URL, jdbcUrl(ydb) + "?disablePrepareDataQuery=true")
3032
.buildSessionFactory();
3133
}
3234

@@ -44,7 +46,8 @@ void integrationTypesTest() {
4446
LocalDateTime.parse("2023-09-16T12:30:00"),
4547
new byte[]{1, 2, 3, 4, 5},
4648
Employee.Enum.ONE,
47-
Employee.Enum.TWO
49+
Employee.Enum.TWO,
50+
UUID.randomUUID()
4851
);
4952

5053
inTransaction(session -> session.persist(employee));
@@ -57,5 +60,22 @@ void integrationTypesTest() {
5760
inTransaction(session -> assertEquals(employee, session
5861
.createQuery("FROM Employee e WHERE e.isActive = false", Employee.class)
5962
.getSingleResult()));
63+
64+
List<String> uuids = List.of(
65+
"123e4567-e89b-12d3-a456-426614174000",
66+
"2d9e498b-b746-9cfb-084d-de4e1cb4736e",
67+
"6E73B41C-4EDE-4D08-9CFB-B7462D9E498B"
68+
);
69+
70+
for (var uuid : uuids) {
71+
employee.setUuid(UUID.fromString(uuid));
72+
inTransaction(session -> session.merge(employee));
73+
inTransaction(session -> {
74+
var actualEmployee = session.find(Employee.class, employee.getId());
75+
76+
assertEquals(employee, actualEmployee);
77+
assertEquals(uuid.toLowerCase(), actualEmployee.getUuid().toString());
78+
});
79+
}
6080
}
6181
}

hibernate-dialect/src/test/java/tech/ydb/hibernate/user/User.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import jakarta.persistence.GeneratedValue;
66
import jakarta.persistence.Id;
77
import jakarta.persistence.Table;
8+
import java.time.Instant;
9+
import java.util.concurrent.ThreadLocalRandom;
810
import lombok.Data;
911
import org.hibernate.annotations.CreationTimestamp;
1012
import org.hibernate.annotations.GenericGenerator;
@@ -14,9 +16,6 @@
1416
import org.hibernate.id.IdentifierGenerator;
1517
import org.hibernate.type.SqlTypes;
1618

17-
import java.time.Instant;
18-
import java.util.concurrent.ThreadLocalRandom;
19-
2019
/**
2120
* @author Kirill Kurdyukov
2221
*/

hibernate-dialect/src/test/java/tech/ydb/hibernate/user/UserRepositoryTest.java

+1-5
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,18 @@ void integrationTest() {
4646
user.setJson(json);
4747

4848
inTransaction(session -> session.persist(user));
49-
5049
inTransaction(
5150
session -> {
5251
User findUser = session.find(User.class, user.getId());
5352

5453
assertEquals("Kirill", findUser.getName());
5554
assertEquals(json, findUser.getJson());
56-
5755
assertTrue(Instant.now().compareTo(findUser.getCreatedAt()) >= 0);
5856
assertTrue(Instant.now().compareTo(findUser.getUpdatedAt()) >= 0);
5957
}
6058
);
6159

6260
User rollbackUser = new User();
63-
64-
user.setId(10);
6561
user.setName("Kirill");
6662

6763
try {
@@ -73,7 +69,7 @@ void integrationTest() {
7369
} catch (RuntimeException ignored) {
7470
}
7571

76-
inTransaction(session -> assertNull(session.find(User.class, 10)));
72+
inTransaction(session -> assertNull(session.find(User.class, rollbackUser.getId())));
7773
}
7874

7975
@Test

shedlock-ydb/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>tech.ydb.dialects</groupId>
88
<artifactId>shedlock-ydb</artifactId>
9-
<version>0.1.0</version>
9+
<version>0.2.0</version>
1010

1111
<packaging>jar</packaging>
1212

shedlock-ydb/src/main/java/tech/ydb/lock/provider/YdbCoordinationServiceLockProvider.java

+47-14
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
package tech.ydb.lock.provider;
22

3+
import java.nio.charset.StandardCharsets;
34
import java.sql.SQLException;
5+
import java.time.Instant;
46
import java.util.Optional;
57
import javax.annotation.PreDestroy;
68
import net.javacrumbs.shedlock.core.LockConfiguration;
79
import net.javacrumbs.shedlock.core.LockProvider;
810
import net.javacrumbs.shedlock.core.SimpleLock;
11+
import net.javacrumbs.shedlock.support.Utils;
912
import org.slf4j.Logger;
1013
import org.slf4j.LoggerFactory;
14+
import tech.ydb.common.retry.RetryForever;
1115
import tech.ydb.coordination.CoordinationClient;
16+
import tech.ydb.coordination.CoordinationSession;
1217
import tech.ydb.coordination.SemaphoreLease;
18+
import tech.ydb.coordination.settings.CoordinationSessionSettings;
19+
import tech.ydb.core.Result;
1320
import tech.ydb.jdbc.YdbConnection;
1421

1522
/**
@@ -32,10 +39,6 @@ public void init() {
3239
for (int i = 0; i < ATTEMPT_CREATE_NODE; i++) {
3340
var status = coordinationClient.createNode(YDB_LOCK_NODE_NAME).join();
3441

35-
if (status.isSuccess()) {
36-
return;
37-
}
38-
3942
if (i == ATTEMPT_CREATE_NODE - 1) {
4043
status.expectSuccess("Failed created coordination service node: " + YDB_LOCK_NODE_NAME);
4144
}
@@ -44,30 +47,60 @@ public void init() {
4447

4548
@Override
4649
public Optional<SimpleLock> lock(LockConfiguration lockConfiguration) {
47-
var coordinationSession = coordinationClient.createSession(YDB_LOCK_NODE_NAME);
50+
var now = Instant.now();
51+
52+
String instanceInfo = "Hostname=" + Utils.getHostname() + ", " +
53+
"Current PID=" + ProcessHandle.current().pid() + ", " +
54+
"CreatedAt=" + now;
55+
56+
logger.info("Instance[{}] is trying to become a leader...", instanceInfo);
4857

49-
coordinationSession.connect().join()
50-
.expectSuccess("Failed creating coordination node session");
58+
var coordinationSession = coordinationClient.createSession(
59+
YDB_LOCK_NODE_NAME, CoordinationSessionSettings.newBuilder()
60+
.withRetryPolicy(new RetryForever(500))
61+
.build()
62+
);
5163

52-
logger.debug("Created coordination node session");
64+
var statusCS = coordinationSession.connect().join();
5365

54-
var semaphoreLease = coordinationSession.acquireEphemeralSemaphore(lockConfiguration.getName(), true,
55-
lockConfiguration.getLockAtMostFor()).join();
66+
if (!statusCS.isSuccess()) {
67+
logger.info("Failed creating coordination session [{}]", coordinationSession);
68+
69+
return Optional.empty();
70+
}
71+
72+
logger.info("Created coordination node session [{}]", coordinationSession);
73+
74+
Result<SemaphoreLease> semaphoreLease = coordinationSession.acquireEphemeralSemaphore(
75+
lockConfiguration.getName(),
76+
true,
77+
instanceInfo.getBytes(StandardCharsets.UTF_8),
78+
lockConfiguration.getLockAtMostFor()
79+
).join();
80+
81+
logger.debug(coordinationSession.toString());
5682

5783
if (semaphoreLease.isSuccess()) {
58-
logger.debug("Semaphore acquired");
84+
logger.info("Instance[{}] acquired semaphore[SemaphoreName={}]", instanceInfo,
85+
semaphoreLease.getValue().getSemaphoreName());
5986

60-
return Optional.of(new YdbSimpleLock(semaphoreLease.getValue()));
87+
return Optional.of(new YdbSimpleLock(semaphoreLease.getValue(), instanceInfo, coordinationSession));
6188
} else {
62-
logger.debug("Semaphore is not acquired");
89+
logger.info("Instance[{}] did not acquire semaphore", instanceInfo);
90+
6391
return Optional.empty();
6492
}
6593
}
6694

67-
private record YdbSimpleLock(SemaphoreLease semaphoreLease) implements SimpleLock {
95+
private record YdbSimpleLock(SemaphoreLease semaphoreLease, String metaInfo,
96+
CoordinationSession coordinationSession) implements SimpleLock {
6897
@Override
6998
public void unlock() {
99+
logger.info("Instance[{}] released semaphore[SemaphoreName={}]", metaInfo, semaphoreLease.getSemaphoreName());
100+
70101
semaphoreLease.release().join();
102+
103+
coordinationSession.close();
71104
}
72105
}
73106

shedlock-ydb/src/test/java/tech/ydb/lock/provider/YdbLockProviderTest.java

+5-13
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,9 @@
22

33
import java.time.Duration;
44
import java.time.Instant;
5-
import java.util.ArrayList;
65
import java.util.Optional;
76
import java.util.concurrent.ExecutionException;
87
import java.util.concurrent.Executors;
9-
import java.util.concurrent.Future;
108
import java.util.concurrent.atomic.AtomicBoolean;
119
import java.util.concurrent.atomic.AtomicInteger;
1210
import net.javacrumbs.shedlock.core.LockConfiguration;
@@ -55,11 +53,9 @@ public void integrationTest() throws ExecutionException, InterruptedException {
5553
var executorServer = Executors.newFixedThreadPool(10);
5654
var atomicInt = new AtomicInteger();
5755
var locked = new AtomicBoolean();
58-
var futures = new ArrayList<Future<?>>();
5956

60-
for (int i = 0; i < 100; i++) {
61-
final var ii = i;
62-
futures.add(executorServer.submit(() -> {
57+
for (int i = 0; i < 10; i++) {
58+
executorServer.submit(() -> {
6359
Optional<SimpleLock> optinal = Optional.empty();
6460

6561
while (optinal.isEmpty()) {
@@ -78,18 +74,14 @@ public void integrationTest() throws ExecutionException, InterruptedException {
7874
throw new RuntimeException(e);
7975
}
8076

81-
atomicInt.addAndGet(ii);
77+
atomicInt.addAndGet(50);
8278
locked.set(false);
8379
simpleLock.unlock();
8480
});
8581
}
86-
}));
82+
}).get();
8783
}
8884

89-
for (Future<?> future : futures) {
90-
future.get();
91-
}
92-
93-
Assertions.assertEquals(4950, atomicInt.get());
85+
Assertions.assertEquals(500, atomicInt.get());
9486
}
9587
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
spring.datasource.driver-class-name=tech.ydb.jdbc.YdbDriver
1+
spring.datasource.driver-class-name=tech.ydb.jdbc.YdbDriver
2+
3+
logging.level.tech.ydb.lock.provider=debug

0 commit comments

Comments
 (0)