Page 3 of 4 FirstFirst 1234 LastLast
Results 21 to 30 of 39

Thread: No transaction in transactional service called from @PostConstruct

  1. #21

    Default

    Hi

    I came across this thread after battling with the same problem of trying to run a transaction in a @PostConstruct method. I managed to get a transaction to run if I annotated the Interface method of the service I am calling from within the PostConstruct method instead of the concrete class.

    Jon

  2. #22

    Default

    Probably it depends on your bean, because as you saw, there is no guarantee the annotations processing beans are already loaded when your @PostConstruct method is called. I still think you'd better still use the @PostInitialzer.
    Last edited by jbaruch; Oct 15th, 2009 at 10:39 AM.

  3. #23
    Join Date
    Nov 2009
    Posts
    24

    Default

    I don't know if you support your code from 2008, or maybe someone else has a better solution for spring 3.x ? I successfully used the @PostConstruct annotation but now, it doen't work anymore. I debugged the code and noticed, that the annotation finder iterates over the current class which is a Proxy instance and all superclasses (which is the Proxy superclass). So it will never ever see the actual annotation in the service class.

    I thought about moving the @PostConstruct to the interface and change the Annotation scanner accordingly. But maybe someone else comes up with a much better Solution?

    Thanks,

    Jan

  4. #24

    Default

    You mean you used the @PostInitialize and it doesn't work in Spring 3.x?

  5. #25
    Join Date
    Nov 2009
    Posts
    24

    Default

    Yes I used it already in 3.0.x and it worked but iin the last days I tried to update to 3.0.1 and back to 3.0.0 and now I doesn't work any more. And I don't know why it worked before. It couldn't. I think spring beans have always been instances of Proxy, correct? So scanning the subclasses, only cannot work.


    I did the following fix in order to scan Interfaces, too:
    Code:
        private <T extends Annotation> T getAnnotation(final Method method, Class<T> annotationClass) {
        	Method classmethod = method;
        	do {
    	    	if(classmethod.isAnnotationPresent(annotationClass)) {
    	    		return classmethod.getAnnotation(annotationClass);
    	    	}
        	}
        	while ((classmethod = getSuperMethod(classmethod)) != null);
        	
        	/* scan interfaces */
        	Class<?>[] interfaces = method.getDeclaringClass().getInterfaces();
        	for (Class<?> class1 : interfaces) {
        		try {
        			Method interfacemethod = class1.getMethod(method.getName(), method.getParameterTypes());
        			if(interfacemethod.isAnnotationPresent(annotationClass)) {
        	    		return interfacemethod.getAnnotation(annotationClass);
        	    	}
        		} catch (NoSuchMethodException e) {
        			
        		}
    		}
        	return null;
    	}
    Cheers,

    Jan

  6. #26

    Default

    The instances aren't always proxies, it depends on their scope and the declared aspects (transaction annotations, custom AspectJ aspects, etc).
    The scanning of interfaces is correct, but org.springframework.util.ClassUtils.getAllInterfac esForClass(Class<?> clazz) should be used to include ones implemented by superclasses.

    Cheers,
    Baruch.

  7. #27

    Default

    Quote Originally Posted by jbaruch View Post
    The instances aren't always proxies, it depends on their scope and the declared aspects (transaction annotations, custom AspectJ aspects, etc).
    The scanning of interfaces is correct, but org.springframework.util.ClassUtils.getAllInterfac esForClass(Class<?> clazz) should be used to include ones implemented by superclasses.
    We seem to have a similar issue and although it was great to happen to come across the @PostInitialize solution it doesn't work for us... Spring 2.5.6-SEC01, GlassFish v3 Final, Java 1.6.0... .

    The odd thing is that in an earlier more constrained example it seemed to work. This is the code we have and all beans are getting constructed fine its just that the initService is not getting called...

    Any ideas???? Thanks You!


    @Service("modalityService")
    public class ModalityServiceImpl implements ModalityService {

    @Autowired
    private ModalityDao modalityDao;

    private ModalityCache modalityCache;

    @PostInitialize
    public void initService() {
    List<Modality> modalityList = this.modalityDao.findAll();
    this.modalityCache = new ModalityCache();
    this.modalityCache.init(modalityList);
    }
    }

  8. #28

    Default

    I decided to try the following code and clearly the @PostConstruct gets executed while the @PostInitialize does not... which at least implies that there are no issues in the code outside the @PostInitialize (for some reason).

    However we can't use the @PostConstruct as the modalityDao bean is not fully available for executing a JPA call on it... hence why we REALLY need @PostInitialize... (very similar reasons to @Transactional not working).

    I can't imagine that the issue would be difficult to solve???

    Thanks in Advance!

    @Service("modalityService")
    public class ModalityServiceImpl implements ModalityService {

    @Autowired
    private ModalityDao modalityDao;

    private ModalityCache modalityCache;

    @PostConstruct
    public void initService2() {
    System.out.println("****************************** ************************************************") ;
    }

    @PostInitialize
    public void initService() {
    System.out.println("//////////////////////////////////////////////////////////////////////////////");
    List<Modality> modalityList = this.modalityDao.findAll();
    this.modalityCache = new ModalityCache();
    this.modalityCache.init(modalityList);
    }

  9. #29

    Default

    Once I added the following to ApplicationContext.xml it worked :-)

    <!-- Following registers PostInitializerRunner so that @PostInitialize will work -->
    <bean id="postInitializer" class="org.lightagents.ws.annotation.PostInitializ erRunner" />

  10. #30

    Default

    Yap, the runner is annotated with @Component, so it should be picked automatically if you use <context:component-scan/>, but if you don't use it, you must declare the runner in your beans xml.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •