11package org .tus .common .sharding .service ;
22
3+ import lombok .RequiredArgsConstructor ;
4+ import org .hibernate .Session ;
5+ import org .tus .common .domain .persistence .NamedArtifact ;
6+ import org .tus .common .domain .persistence .PersistedObject ;
7+ import org .tus .common .domain .persistence .QueryPostProcessor ;
38import org .tus .common .domain .persistence .QueryService ;
9+ import org .tus .common .domain .persistence .SimplePersistedObject ;
10+ import org .tus .common .domain .persistence .UniqueNamedArtifact ;
411import org .tus .common .sharding .util .ShardingUtil ;
512
13+ import java .util .HashMap ;
614import java .util .List ;
715import java .util .Map ;
816
917/**
1018 * Implementation of ShardingAwareQueryService.
11- *
19+ *
1220 * This implementation extends the base QueryService functionality with
13- * sharding-aware operations. Most operations delegate to the base QueryService,
14- * as ShardingSphere handles the routing transparently .
21+ * sharding-aware operations. All sharded queries include the sharding value
22+ * in the HQL so ShardingSphere can route to the correct shard(s) .
1523 */
24+ @ RequiredArgsConstructor
1625public class ShardingAwareQueryServiceImpl implements ShardingAwareQueryService {
1726
27+ /**
28+ * Parameter name used when appending sharding key IN clause in queryWithShardingKeys.
29+ */
30+ public static final String SHARDING_KEYS_PARAM = "__shardingKeys" ;
31+
1832 private final QueryService delegate ;
1933
20- public ShardingAwareQueryServiceImpl (QueryService delegate ) {
21- this .delegate = delegate ;
22- }
2334
2435 @ Override
2536 public <T > T findObjectByIdWithShardingKey (Class <T > clazz , String id , Long shardingKey ) {
26- // ShardingSphere will automatically route based on sharding key in WHERE clause
27- // We need to include the sharding key in the query
28- String hql = "from " + clazz .getName () + " where id = :id" ;
29- Map <String , Object > params = Map .of ("id" , id );
30-
31- // If the entity has a sharding key field, include it in the query
32- // This ensures ShardingSphere routes correctly
33- // Note: The actual routing is handled by ShardingSphere based on table configuration
37+ return findObjectByIdWithShardingKey (clazz , id , "userId" , shardingKey );
38+ }
39+
40+ @ Override
41+ public <T > T findObjectByIdWithShardingKey (Class <T > clazz , String id , String shardingKeyPropertyName , Object shardingKeyValue ) {
42+ if (shardingKeyPropertyName == null || shardingKeyPropertyName .isBlank ()) {
43+ throw new IllegalArgumentException ("shardingKeyPropertyName must not be null or blank" );
44+ }
45+ if (shardingKeyValue == null ) {
46+ throw new IllegalArgumentException ("shardingKeyValue must not be null for shard routing" );
47+ }
48+ String hql = "from " + clazz .getName () + " where id = :id and " + shardingKeyPropertyName + " = :shardingKeyValue" ;
49+ Map <String , Object > params = new HashMap <>();
50+ params .put ("id" , id );
51+ params .put ("shardingKeyValue" , shardingKeyValue );
3452 Object result = delegate .querySingle (hql , params , null );
3553 return result != null ? clazz .cast (result ) : null ;
3654 }
3755
3856 @ Override
3957 public List queryWithShardingKeys (String hql , Map <String , Object > namedParameters , List <Long > shardingKeys ) {
40- // ShardingSphere automatically handles IN queries across shards
41- // Just execute the query normally - ShardingSphere will route correctly
4258 if (shardingKeys != null && !shardingKeys .isEmpty ()) {
43- // Add sharding keys to parameters if needed
44- Map <String , Object > params = new java .util .HashMap <>(namedParameters );
59+ Map <String , Object > params = namedParameters == null ? new HashMap <>() : new HashMap <>(namedParameters );
4560 params .put ("shardingKeys" , shardingKeys );
4661 return delegate .query (hql , params );
4762 }
48- return delegate .query (hql , namedParameters );
63+ return delegate .query (hql , namedParameters != null ? namedParameters : Map .of ());
64+ }
65+
66+ @ Override
67+ public List queryWithShardingKeys (String hql , Map <String , Object > namedParameters , String shardingKeyPropertyName , List <?> shardingKeys ) {
68+ if (shardingKeyPropertyName == null || shardingKeyPropertyName .isBlank ()) {
69+ throw new IllegalArgumentException ("shardingKeyPropertyName must not be null or blank" );
70+ }
71+ Map <String , Object > params = namedParameters == null ? new HashMap <>() : new HashMap <>(namedParameters );
72+ if (shardingKeys != null && !shardingKeys .isEmpty ()) {
73+ String condition = shardingKeyPropertyName + " IN (:" + SHARDING_KEYS_PARAM + ")" ;
74+ String normalizedHql = hql .trim ();
75+ boolean hasWhere = normalizedHql .toUpperCase ().contains (" WHERE " );
76+ String fullHql = hasWhere ? (normalizedHql + " AND " + condition ) : (normalizedHql + " WHERE " + condition );
77+ params .put (SHARDING_KEYS_PARAM , shardingKeys );
78+ return delegate .query (fullHql , params );
79+ }
80+ return delegate .query (hql , params );
4981 }
5082
5183 @ Override
5284 public ShardInfo getShardInfo (Long shardingKey , int shardingCount , int databaseCount , int tableCount ) {
5385 int dbIndex = ShardingUtil .calculateDatabaseShard (shardingKey , shardingCount , databaseCount );
5486 int tableIndex = ShardingUtil .calculateTableShard (shardingKey , tableCount );
55-
87+
5688 String dbName = "ds_" + dbIndex ;
5789 String tableName = "t_" + tableIndex ; // Base name should be provided
58-
90+
5991 return new ShardInfo (dbIndex , tableIndex , dbName , tableName );
6092 }
6193
6294 // Delegate all QueryService methods to the underlying service
6395 @ Override
64- public org . hibernate . Session openSession () {
96+ public Session openSession () {
6597 return delegate .openSession ();
6698 }
6799
@@ -76,7 +108,7 @@ public List query(String hql, Object... params) {
76108 }
77109
78110 @ Override
79- public List query (String hql , org . tus . common . domain . persistence . QueryPostProcessor post , Object ... params ) {
111+ public List query (String hql , QueryPostProcessor post , Object ... params ) {
80112 return delegate .query (hql , post , params );
81113 }
82114
@@ -86,7 +118,7 @@ public List query(String hql, Map<String, Object> namedParams) {
86118 }
87119
88120 @ Override
89- public List query (String hql , Map <String , Object > namedParams , org . tus . common . domain . persistence . QueryPostProcessor post ) {
121+ public List query (String hql , Map <String , Object > namedParams , QueryPostProcessor post ) {
90122 return delegate .query (hql , namedParams , post );
91123 }
92124
@@ -96,13 +128,13 @@ public List pagedQuery(String hql, Map<String, Object> namedParameters, Integer
96128 }
97129
98130 @ Override
99- public List pagedQuery (String hql , Map <String , Object > namedParameters , Integer pageStart , Integer pageSize ,
100- org . tus . common . domain . persistence . QueryPostProcessor post ) {
131+ public List pagedQuery (String hql , Map <String , Object > namedParameters , Integer pageStart , Integer pageSize ,
132+ QueryPostProcessor post ) {
101133 return delegate .pagedQuery (hql , namedParameters , pageStart , pageSize , post );
102134 }
103135
104136 @ Override
105- public <T extends org . tus . common . domain . persistence . SimplePersistedObject > T save (T item ) {
137+ public <T extends SimplePersistedObject > T save (T item ) {
106138 return delegate .save (item );
107139 }
108140
@@ -127,7 +159,7 @@ public <T> void deleteAll(List<T> objects) {
127159 }
128160
129161 @ Override
130- public <T extends org . tus . common . domain . persistence . SimplePersistedObject > List <T > saveAll (List <T > itemList ) {
162+ public <T extends SimplePersistedObject > List <T > saveAll (List <T > itemList ) {
131163 return delegate .saveAll (itemList );
132164 }
133165
@@ -137,12 +169,12 @@ public <T> T save(T item) {
137169 }
138170
139171 @ Override
140- public <T extends org . tus . common . domain . persistence . SimplePersistedObject > T delete (T item ) {
172+ public <T extends SimplePersistedObject > T delete (T item ) {
141173 return delegate .delete (item );
142174 }
143175
144176 @ Override
145- public <T extends org . tus . common . domain . persistence . SimplePersistedObject > List <T > mergeAll (List <T > itemList ) {
177+ public <T extends SimplePersistedObject > List <T > mergeAll (List <T > itemList ) {
146178 return delegate .mergeAll (itemList );
147179 }
148180
@@ -167,51 +199,49 @@ public int sqlUpdate(String sql, Object... params) {
167199 }
168200
169201 @ Override
170- public <T extends org . tus . common . domain . persistence . UniqueNamedArtifact > T findObjectByName (Class <T > clazz , String name ) {
202+ public <T extends UniqueNamedArtifact > T findObjectByName (Class <T > clazz , String name ) {
171203 return delegate .findObjectByName (clazz , name );
172204 }
173205
174206 @ Override
175- public <T extends org . tus . common . domain . persistence . SimplePersistedObject > T findSimpleObjectById (Class <T > clazz , String objId , String typeName ) {
207+ public <T extends SimplePersistedObject > T findSimpleObjectById (Class <T > clazz , String objId , String typeName ) {
176208 return delegate .findSimpleObjectById (clazz , objId , typeName );
177209 }
178210
179211 @ Override
180- public <T extends org . tus . common . domain . persistence . SimplePersistedObject > T findSimpleObjectById (Class <T > clazz , String objId ) {
212+ public <T extends SimplePersistedObject > T findSimpleObjectById (Class <T > clazz , String objId ) {
181213 return delegate .findSimpleObjectById (clazz , objId );
182214 }
183215
184216 @ Override
185- public <T extends org . tus . common . domain . persistence . UniqueNamedArtifact > T findObjectByName (Class <T > clazz , String name ,
186- org . tus . common . domain . persistence . QueryPostProcessor post ) {
217+ public <T extends UniqueNamedArtifact > T findObjectByName (Class <T > clazz , String name ,
218+ QueryPostProcessor post ) {
187219 return delegate .findObjectByName (clazz , name , post );
188220 }
189221
190222 @ Override
191- public <T extends org . tus . common . domain . persistence . PersistedObject > T findObjectById (Class <T > clazz , String id ) {
223+ public <T extends PersistedObject > T findObjectById (Class <T > clazz , String id ) {
192224 return delegate .findObjectById (clazz , id );
193225 }
194226
195227 @ Override
196- public <T extends org .tus .common .domain .persistence .PersistedObject > T findObjectById (Class <T > clazz , String id ,
197- org .tus .common .domain .persistence .QueryPostProcessor post ) {
228+ public <T extends PersistedObject > T findObjectById (Class <T > clazz , String id , QueryPostProcessor post ) {
198229 return delegate .findObjectById (clazz , id , post );
199230 }
200231
201232 @ Override
202- public <T extends org . tus . common . domain . persistence . PersistedObject > T findObjectByIdOrName (Class <T > clazz , String idOrName ) {
233+ public <T extends PersistedObject > T findObjectByIdOrName (Class <T > clazz , String idOrName ) {
203234 return delegate .findObjectByIdOrName (clazz , idOrName );
204235 }
205236
206237 @ Override
207- public <T extends org .tus .common .domain .persistence .PersistedObject > T findObjectByIdOrName (Class <T > clazz , String idName ,
208- org .tus .common .domain .persistence .QueryPostProcessor post ) {
238+ public <T extends PersistedObject > T findObjectByIdOrName (Class <T > clazz , String idName , QueryPostProcessor post ) {
209239 return delegate .findObjectByIdOrName (clazz , idName , post );
210240 }
211241
212242 @ Override
213- public <T extends org . tus . common . domain . persistence . PersistedObject > List <T > findObjectsByAndingParams (Class <T > tClass ,
214- Map <String , String > params ) {
243+ public <T extends PersistedObject > List <T > findObjectsByAndingParams (Class <T > tClass ,
244+ Map <String , String > params ) {
215245 return delegate .findObjectsByAndingParams (tClass , params );
216246 }
217247
@@ -236,13 +266,12 @@ public int executeQuery(String hql, Map<String, Object> namedParameters) {
236266 }
237267
238268 @ Override
239- public Object querySingle (String hql , Map <String , Object > namedParameters ,
240- org .tus .common .domain .persistence .QueryPostProcessor post ) {
269+ public Object querySingle (String hql , Map <String , Object > namedParameters , QueryPostProcessor post ) {
241270 return delegate .querySingle (hql , namedParameters , post );
242271 }
243272
244273 @ Override
245- public <T extends org . tus . common . domain . persistence . NamedArtifact > T findOrSave (String hql , Map <String , Object > namedParameters , T item ) {
274+ public <T extends NamedArtifact > T findOrSave (String hql , Map <String , Object > namedParameters , T item ) {
246275 return delegate .findOrSave (hql , namedParameters , item );
247276 }
248277}
0 commit comments