Skip to content

Commit 95bb302

Browse files
authored
Merge pull request #15423 from apache/test/query-connection-routing
2 parents c800692 + a514a04 commit 95bb302

File tree

3 files changed

+163
-0
lines changed

3 files changed

+163
-0
lines changed

grails-data-hibernate5/core/src/test/groovy/org/grails/orm/hibernate/connections/DataServiceMultiDataSourceSpec.groovy

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import spock.lang.Shared
2424
import spock.lang.Specification
2525

2626
import grails.gorm.annotation.Entity
27+
import grails.gorm.services.Query
2728
import grails.gorm.services.Service
2829
import grails.gorm.transactions.Transactional
2930
import org.grails.datastore.gorm.GormEnhancer
@@ -298,6 +299,93 @@ class DataServiceMultiDataSourceSpec extends Specification {
298299
productService.count() == productDataService.count()
299300
}
300301

302+
void "@Query find-one routes to books datasource - abstract service"() {
303+
given: 'a product saved on books'
304+
productService.save(new Product(name: 'QueryOne', amount: 50))
305+
306+
when: 'we find one by HQL query'
307+
def found = productService.findOneByQuery('QueryOne')
308+
309+
then: 'the correct entity is returned from books'
310+
found != null
311+
found.name == 'QueryOne'
312+
found.amount == 50
313+
}
314+
315+
void "@Query find-one returns null for non-existent - abstract service"() {
316+
expect: 'null for non-existent product'
317+
productService.findOneByQuery('NonExistent') == null
318+
}
319+
320+
void "@Query find-all routes to books datasource - abstract service"() {
321+
given: 'products saved on books with varying amounts'
322+
productService.save(new Product(name: 'Expensive1', amount: 500))
323+
productService.save(new Product(name: 'Expensive2', amount: 600))
324+
productService.save(new Product(name: 'Cheap1', amount: 10))
325+
326+
when: 'we find all by HQL query with threshold'
327+
def found = productService.findAllByQuery(400)
328+
329+
then: 'only matching products from books are returned'
330+
found.size() == 2
331+
found*.name.containsAll(['Expensive1', 'Expensive2'])
332+
}
333+
334+
void "@Query update routes to books datasource - abstract service"() {
335+
given: 'a product saved on books'
336+
productService.save(new Product(name: 'UpdateTarget', amount: 100))
337+
338+
when: 'we update amount by HQL query'
339+
def updated = productService.updateAmountByName('UpdateTarget', 999)
340+
341+
then: 'one row updated'
342+
updated == 1
343+
344+
and: 'the change is reflected on books'
345+
productService.findByName('UpdateTarget').amount == 999
346+
}
347+
348+
void "@Query find-one routes to books datasource - interface service"() {
349+
given: 'a product saved on books'
350+
productService.save(new Product(name: 'InterfaceQueryOne', amount: 75))
351+
352+
when: 'we find one by HQL query through the interface service'
353+
def found = productDataService.findOneByQuery('InterfaceQueryOne')
354+
355+
then: 'the correct entity is returned from books'
356+
found != null
357+
found.name == 'InterfaceQueryOne'
358+
found.amount == 75
359+
}
360+
361+
void "@Query find-all routes to books datasource - interface service"() {
362+
given: 'products saved on books'
363+
productService.save(new Product(name: 'IfaceExpensive1', amount: 500))
364+
productService.save(new Product(name: 'IfaceExpensive2', amount: 600))
365+
productService.save(new Product(name: 'IfaceCheap1', amount: 10))
366+
367+
when: 'we find all by HQL query through the interface service'
368+
def found = productDataService.findAllByQuery(400)
369+
370+
then: 'only matching products from books are returned'
371+
found.size() == 2
372+
found*.name.containsAll(['IfaceExpensive1', 'IfaceExpensive2'])
373+
}
374+
375+
void "@Query update routes to books datasource - interface service"() {
376+
given: 'a product saved on books'
377+
productService.save(new Product(name: 'InterfaceUpdate', amount: 100))
378+
379+
when: 'we update amount by HQL query through the interface service'
380+
def updated = productDataService.updateAmountByName('InterfaceUpdate', 888)
381+
382+
then: 'one row updated'
383+
updated == 1
384+
385+
and: 'the change is reflected on books'
386+
productDataService.findByName('InterfaceUpdate').amount == 888
387+
}
388+
301389
}
302390

303391
@Entity
@@ -338,6 +426,16 @@ abstract class ProductService {
338426
* Tests that SaveImplementer routes multi-arg saves through connection-aware API.
339427
*/
340428
abstract Product saveProduct(String name, Integer amount)
429+
430+
@Query("from ${Product p} where $p.name = $name")
431+
abstract Product findOneByQuery(String name)
432+
433+
434+
@Query("from ${Product p} where $p.amount >= $minAmount")
435+
abstract List<Product> findAllByQuery(Integer minAmount)
436+
437+
@Query("update ${Product p} set $p.amount = $newAmount where $p.name = $name")
438+
abstract Number updateAmountByName(String name, Integer newAmount)
341439
}
342440

343441
/**
@@ -362,4 +460,13 @@ interface ProductDataService {
362460
Product findByName(String name)
363461

364462
List<Product> findAllByName(String name)
463+
464+
@Query("from ${Product p} where $p.name = $name")
465+
Product findOneByQuery(String name)
466+
467+
@Query("from ${Product p} where $p.amount >= $minAmount")
468+
List<Product> findAllByQuery(Integer minAmount)
469+
470+
@Query("update ${Product p} set $p.amount = $newAmount where $p.name = $name")
471+
Number updateAmountByName(String name, Integer newAmount)
365472
}

grails-test-examples/hibernate5/grails-data-service-multi-datasource/grails-app/services/example/ProductService.groovy

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package example
2121

22+
import grails.gorm.services.Query
2223
import grails.gorm.services.Service
2324
import grails.gorm.transactions.Transactional
2425

@@ -45,4 +46,13 @@ abstract class ProductService {
4546
abstract Product findByName(String name)
4647

4748
abstract List<Product> findAllByName(String name)
49+
50+
@Query("from ${Product p} where $p.name = $name")
51+
abstract Product findOneByQuery(String name)
52+
53+
@Query("from ${Product p} where $p.amount >= $minAmount")
54+
abstract List<Product> findAllByQuery(Integer minAmount)
55+
56+
@Query("update ${Product p} set $p.amount = $newAmount where $p.name = $name")
57+
abstract Number updateAmountByName(String name, Integer newAmount)
4858
}

grails-test-examples/hibernate5/grails-data-service-multi-datasource/src/integration-test/groovy/functionaltests/DataServiceMultiDataSourceSpec.groovy

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,50 @@ class DataServiceMultiDataSourceSpec extends Specification {
131131
found.size() == 2
132132
found.every { it.name == 'Duplicate' }
133133
}
134+
135+
void "@Query find-one routes to secondary datasource"() {
136+
given:
137+
productService.save(new Product(name: 'QueryOne', amount: 50))
138+
139+
when:
140+
def found = productService.findOneByQuery('QueryOne')
141+
142+
then:
143+
found != null
144+
found.name == 'QueryOne'
145+
found.amount == 50
146+
}
147+
148+
void "@Query find-one returns null for non-existent"() {
149+
expect:
150+
productService.findOneByQuery('NonExistent') == null
151+
}
152+
153+
void "@Query find-all routes to secondary datasource"() {
154+
given:
155+
productService.save(new Product(name: 'Expensive1', amount: 500))
156+
productService.save(new Product(name: 'Expensive2', amount: 600))
157+
productService.save(new Product(name: 'Cheap1', amount: 10))
158+
159+
when:
160+
def found = productService.findAllByQuery(400)
161+
162+
then:
163+
found.size() == 2
164+
found*.name.containsAll(['Expensive1', 'Expensive2'])
165+
}
166+
167+
void "@Query update routes to secondary datasource"() {
168+
given:
169+
productService.save(new Product(name: 'UpdateTarget', amount: 100))
170+
171+
when:
172+
def updated = productService.updateAmountByName('UpdateTarget', 999)
173+
174+
then:
175+
updated == 1
176+
177+
and:
178+
productService.findByName('UpdateTarget').amount == 999
179+
}
134180
}

0 commit comments

Comments
 (0)