Grails
  1. Grails
  2. GRAILS-3060

@PostConstruct fails silently for transactional services

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.0.2
    • Fix Version/s: None
    • Component/s: Services
    • Labels:
      None
    • Environment:
      Java 1.6
      Windows XP

      Description

      I'm annotating some of my service methods using @javax.annotation.PostConstruct. This ensures spring will call that method on the bean after the bean is created. To get this working, I added " bean(org.springframework.context.annotation.CommonAnnotationBeanPostProcessor)" to resources.groovy.

      This is failing silently if either the service has "static transactional = true" or if the service is injected into another service that has "static transactional = true".

      See the attached sample grails project created with "grails bug-report". If you run "grails run-app", you will see the message on stdout: "setUp() annotated with @PostConstruct called in PostConstructService". If you change the transactional property to false in services/PostConstructService.groovy or services/UsesPostConstructService.groovy, then the @PostConstruct method will not be called and the message above will not be printed to stdout.

      A workaround for this is to implement Spring's InitializingBean interface and define afterPropertiesSet(). This is a little more invasive than using the @PostConstruct annotation.

      Thanks,
      Jon

        Activity

        Hide
        Mingfai Ma added a comment -

        with the following configuration, I could use @PostConstruct for services in bean creation without problem:

        <beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:context="http://www.springframework.org/schema/context"
               xmlns:util="http://www.springframework.org/schema/util"
               xmlns:aop="http://www.springframework.org/schema/aop"
               xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        						http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        			            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
        			            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
        
           <context:component-scan base-package="come.acme"/>
           ... 
        

        The above configuration essentially add AutowiredAnnotationBeanPostProcessor on top of the CommonAnnotationBeanPostProcessor, that support fine-grained control. So, i think if configured correctly, @PostConstruct works fine in the latest stable version of Grails. (Grails 1.0.3+)

        Reference: http://www.infoq.com/articles/spring-2.5-part-1

        however, i suspect, in development mode, when the bean is changed, the @PostConstruct method is not called again. The service reload issue is complex and it may or may not related to @PostConstruct. If possible, please verify the development mode reload behavior.

        Show
        Mingfai Ma added a comment - with the following configuration, I could use @PostConstruct for services in bean creation without problem: <beans xmlns= "http: //www.springframework.org/schema/beans" xmlns:xsi= "http: //www.w3.org/2001/XMLSchema-instance" xmlns:context= "http: //www.springframework.org/schema/context" xmlns:util= "http: //www.springframework.org/schema/util" xmlns:aop= "http: //www.springframework.org/schema/aop" xsi:schemaLocation="http: //www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http: //www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http: //www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd http: //www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <context:component-scan base- package = "come.acme" /> ... The above configuration essentially add AutowiredAnnotationBeanPostProcessor on top of the CommonAnnotationBeanPostProcessor, that support fine-grained control. So, i think if configured correctly, @PostConstruct works fine in the latest stable version of Grails. (Grails 1.0.3+) Reference: http://www.infoq.com/articles/spring-2.5-part-1 however , i suspect, in development mode, when the bean is changed, the @PostConstruct method is not called again. The service reload issue is complex and it may or may not related to @PostConstruct. If possible, please verify the development mode reload behavior.
        Hide
        Mingfai Ma added a comment -

        Just an update, in Grails 1.1 beta 3, @PostConstruct still do not work against service with

        boolean transactional = false
        

        if this problem can't be fixed soon, it would be nice to have a way to disable transactional globally. refer to GRAILS-3964

        Show
        Mingfai Ma added a comment - Just an update, in Grails 1.1 beta 3, @PostConstruct still do not work against service with boolean transactional = false if this problem can't be fixed soon, it would be nice to have a way to disable transactional globally. refer to GRAILS-3964
        Hide
        Mingfai Ma added a comment -

        for the last comment, i meant:

        boolean transactional = true
        
        Show
        Mingfai Ma added a comment - for the last comment, i meant: boolean transactional = true

          People

          • Assignee:
            Unassigned
            Reporter:
            Jon Gunnip
          • Votes:
            2 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Last Reviewed:

              Development