Search code examples
grails

Grails Data Service Cannot Use Regular Service


Happy Another Covid Day. When I use generate-all, Grails creates the Data Service for me. I begin to understand what a data service is.

I also have my own service for my Author and Book classes to use. I name my service ImportService. I have methods in the ImportService to clean up my book data read from a CSV file before the Data Service saves my books to the database. I also follow the instruction to make the Data Service an Abstract Class. So, I can put my own method in the Data Service.

Since the Author has its own AuthorService, and the Book has its own BookService, I want the different Data Service to access the method in my ImportService. So, I don't have to copy and paste the import CSV code multiple times. So, I put the line ImportService importService in the AuthorServie class and the BookService class. That does not go well. importService is always NULL inside the Data Service classes. I google the problem. They say I cannot inject another service to the grails.gorm.services.Service.

There is a post that says to make a bean. I am new to Grails. I have no idea what they are talking about even with the codes posted. Part of my background is Assembly Language, C, and Pascal. My head is filled with lingo like Top Down, Subroutine, library, Address, and Pointer. I have no idea what a Bean is.

This is what it is. I am wondering whether this is a bug or by design that you cannot inject a service to the gorm service.

Thanks for your "Pointer".


Solution

  • See the project at https://github.com/jeffbrown/tom6502servicedi. That project uses Grails 4.0.3 and GORM 7.0.7.

    https://github.com/jeffbrown/tom6502servicedi/blob/main/grails-app/services/tom6502servicedi/ImportService.groovy

    package tom6502servicedi
    
    class ImportService {
    
        int getSomeNumber() {
            42
        }
    }
    

    https://github.com/jeffbrown/tom6502servicedi/blob/917c51ee173e7bb6844ca7d40ced5afbb8d9063f/grails-app/services/tom6502servicedi/AuthorService.groovy

    package tom6502servicedi
    
    import grails.gorm.services.Service
    import org.springframework.beans.factory.annotation.Autowired
    
    @Service(Author)
    abstract class AuthorService {
    
        @Autowired
        ImportService importService
    
        // ...
    
        int getSomeNumberFromImportService() {
            importService.someNumber
        }
    }
    

    https://github.com/jeffbrown/tom6502servicedi/blob/917c51ee173e7bb6844ca7d40ced5afbb8d9063f/grails-app/controllers/tom6502servicedi/AuthorController.groovy

    package tom6502servicedi
    
    import grails.validation.ValidationException
    import static org.springframework.http.HttpStatus.*
    
    class AuthorController {
    
        AuthorService authorService
    
        // ...
    
        def someNumber() {
            render "The Number Is ${authorService.someNumberFromImportService}"
        }
    }
    

    Sending a request to that someNumber action will verify that the ImportService is injected into the AuthorService and the AuthorService is injected into the AuthorController.

    $ curl http://localhost:8080/author/someNumber
    The Number Is 42