2013-03-05 7 views
27

Im usando Primavera sociale nella mia domanda:superclasse non ha costruttori nulli, ma senza argomenti è stata data

<spring.framework.version>3.2.0.RELEASE</spring.framework.version> 
<hibernate.version>4.1.9.Final</hibernate.version> 
<commons-dbcp.version>1.4</commons-dbcp.version> 
<org.springframework.social-version>1.1.0.BUILD-SNAPSHOT</org.springframework.social-version> 
<org.springframework.social.facebook-version>1.1.0.BUILD-SNAPSHOT</org.springframework.social.facebook-version> 
<org.springframework-version>3.2.1.RELEASE</org.springframework-version> 
<org.springframework.security.crypto-version>3.1.3.RELEASE</org.springframework.security.crypto-version> 

Quando applico

private final Facebook facebook; 

@Inject 
public SearchController(Facebook facebook) { 
    this.facebook = facebook; 
} 

Alla mia HomeController:

@Controller 
public class HomeController { 


    private final Facebook facebook; 

    @Inject 
    public HomeController(Facebook facebook) { 
     this.facebook = facebook; 
    } 

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class); 

    /** 
    * Simply selects the home view to render by returning its name. 
    */ 
    @RequestMapping(value = "/", method = RequestMethod.GET) 
    public String home(Model model) { 
     return "home"; 
    } 

} 

Il l'iniezione funziona come intenta e posso ottenere informazioni da facebook. Tuttavia, quando ho applicarlo a uno dei miei altri Cotrollers come questo

@Controller 
@Transactional 
@RequestMapping(value = "/search") 
public class SearchController { 

    private static final Logger logger = LoggerFactory.getLogger(SearchController.class); 

    private final Facebook facebook; 

    @Inject 
    public SearchController(Facebook facebook) { 
     this.facebook = facebook; 
    } 

    @PersistenceContext 
    private EntityManager entityManager; 

    ... 

ho questo errore:

mar 05, 2013 12:46:36 EM org.apache.catalina.core.StandardWrapperValve invoke 
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/project] threw exception [Request processing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'searchController' defined in file [C:\Users\Nilsi\Downloads\springsource\vfabric-tc-server-developer-2.7.2.RELEASE\base-instance\wtpwebapps\course_info\WEB-INF\classes\com\courseinfo\project\controller\SearchController.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.courseinfo.project.controller.SearchController]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given] with root cause 
java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given 
    at org.springframework.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721) 
    at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:499) 
    at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33) 
    at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25) 
    at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216) 
    at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377) 
    at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285) 
    at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:205) 
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:111) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:477) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362) 
    at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:412) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1492) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:524) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1117) 
    at org.springframework.web.method.HandlerMethod.createWithResolvedBean(HandlerMethod.java:202) 
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:233) 
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(AbstractHandlerMethodMapping.java:55) 
    at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:297) 
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1091) 
    at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1076) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:896) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:920) 
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:827) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:801) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:722) 

La mia ipotesi è che non riesco a iniettare facebook per un controller con l'annotazione @ transazionale? Ho cercato su Google ma non trovo alcuna soluzione a questo.

+0

Funziona se si utilizza l'iniezione basata su proprietà? –

+0

Wow, ha funzionato! se lo metti come risposta, lo contrassegnerò come corretto. Ho semplicemente cancellato il costruttore e modificato in: @Inject private Facebook facebook; Testato prima, ma non riuscivo a farlo funzionare, la variabile originariamente era definitiva. (Era finale nel codice di esempio di Springs da cui l'ho preso). – nilsi

risposta

53

CGlib ha una restrizione importante: la classe di destinazione deve fornire un costruttore predefinito.

Se si utilizza l'iniezione basata su proprietà invece dell'iniezione basata su costruttore, il problema scompare.

+40

Espansione su questa risposta: Questo avrebbe funzionato bene tramite l'iniezione del costruttore (che è preferibile) se non avessi aggiunto "@ Transactional" al controller. Una volta aggiunto '@ Transactional', AOP prende il via e deve essere creato un proxy. CGLib ha bisogno di un costruttore predefinito. Un'altra soluzione è configurare le transazioni Spring per utilizzare AspectJ invece dei proxy. Ciò richiede un po 'più di setup, ma consentirebbe transazioni su una classe senza alcun costruttore predefinito. –

+3

Questo è un ottimo commento! Penso che dovrebbe essere aggiunto alla risposta. –

+6

Prima della Spring 4, le classi proxy basate su CGLIB richiedono un costruttore predefinito. E questa non è la limitazione della libreria CGLIB, ma Spring stessa. Fortunatamente, a partire dalla primavera 4 questo non è più un problema. Le classi proxy basate su CGLIB non richiedono più un costruttore predefinito. Vedi questo articolo: http://blog.codeleak.pl/2014/07/spring-4-cglib-based-proxy-classes-with-no-default-ctor.html –

0

Ho appena creato un costruttore predefinito vuoto per gestire questo.