junaidp
junaidp

Reputation: 11201

Inject Hibernate sessionfactory in a Grails service

I am struggling with using Hibernate simply for saving a user in Grails, nothing else. I could not find any example/tutorial for this one.

I am not looking for GORM, scaffolding, etc. WI am trying to use sessionFactory in my service to persist a UserEntity.

        def sessionFactory
        def hibSession = sessionFactory.getCurrentSession()
        UserEntity userEntity = new UserEntity();
        userEntity.setEmail("grails")
        hibSession.save(userEntity);
        hibSession.flush()

But it says sessionFactory is null.

It is not clear to me how to access sessionfactory in my service.

Please guide.

Upvotes: 0

Views: 2443

Answers (1)

nst1nctz
nst1nctz

Reputation: 333

Edit 2: Create an integration test to verify that sessionFactory is injected properly. Run the following grails command:

create-integration-test <package>.MyService

You may have to delete the unit test file MyServiceSpec.groovy in the test/unit directory if it exists.

Implement the following Test:

    class MyServiceSpec extends Specification {

    def myService

    def setup() {
    }

    def cleanup() {
    }

    void "test something"() {
        when:
        def u = myService.serviceMethod()

        then:
        u != null

    }
}

You also need to change your service method to return the user instance to make the test work as I did below.

Run test-app <package.MyService -integration

Does this test pass? If not, please provide further information about your development environment.

Edit: This probably doesn't matter in this case, but what is your grails version/development environment? It is better to specify that when asking a question.

Firstly, why are you not using GORM? I don't see many benefits from using grails without using it's core features. Why do you want to use sessionFactory to manage the ORM instead of GORM? GORM does the same under the hood if you just call new UserEntity(email:'grails').save().

This leads me to my next point: you are not using the features of Groovy either. In Groovy, you can use map constructors like I did above and also use setter methods like that: user.email = 'grails'.

Furthermore, after a service method is called, the session is flushed automatically, so you don't need to flush it manually. This only applies, however, if the service method is transactional -- and they are by default.

I don't want to discourage you from using Grails, but IMHO you don't leverage the powerful tools of Groovy and Grails and rather code Java, Spring and Hibernate. You only make use of the conventions, such as Domain Classes, Controllers, Views and Services, and I don't know if that is worth it. But it is your choice, your approach surprises me to say the least.

Secondly, this is the way your code works:

MyService.groovy:

@Transactional
class MyService {

    def sessionFactory

    UserEntity serviceMethod() {
        def s = sessionFactory.currentSession
        def u = new UserEntity(email:'grails')
        s.save(u)
        //or: 
        //def user = new UserEntity()
        //user.email = 'grails'
        //s.save(user)
        //or do it the Java way like in your code 

        u.id ? u : null                
    }
}

sessionFactory needs to be declared as a field in your service so that spring can inject it by naming convention at startup. Judging from your code, you should do some further reading on spring and dependency injection. You could have a look at the official Spring documentation or, to learn it by doing step by step first, at Tutorialspoint.`

Upvotes: 1

Related Questions