hibernate - Spring Boot Test: No qualifying bean of type [javax.persistence.EntityManagerFactory] is defined -
i trying set test context under spring boot, defined testapplicationcontext so:
@runwith(springjunit4classrunner.class) @springapplicationconfiguration(classes = {mvcconfig.class,securityconfig.class}) @webappconfiguration @enableautoconfiguration @propertysource({ "classpath:persistence.properties" }) @componentscan public class testapplicationcontext { @autowired private environment env; @bean public embeddedservletcontainerfactory servletcontainer() { tomcatembeddedservletcontainerfactory factory = new tomcatembeddedservletcontainerfactory(); factory.setport(9000); factory.setsessiontimeout(10, timeunit.minutes); //factory.adderrorpages(new errorpage(httpstatus.404, "/notfound.html")); return factory; } @bean public platformtransactionmanager transactionmanager(entitymanagerfactory emf) { jpatransactionmanager transactionmanager = new jpatransactionmanager(); transactionmanager.setentitymanagerfactory(emf); return transactionmanager; } @bean public localcontainerentitymanagerfactorybean entitymanagerfactory() { localcontainerentitymanagerfactorybean em = new localcontainerentitymanagerfactorybean(); em.setdatasource(hsqldatasource()); em.setpackagestoscan(new string[] { "com.touchcorp.touchppoint.model" }); jpavendoradapter vendoradapter = new hibernatejpavendoradapter(); em.setjpavendoradapter(vendoradapter); em.setjpaproperties(buildhibernateproperties()); return em; } @bean public datasource hsqldatasource() { basicdatasource basicdatasource = new basicdatasource(); basicdatasource.setdriverclassname(org.hsqldb.jdbcdriver.class.getname()); basicdatasource.setusername("sa"); basicdatasource.setpassword(""); basicdatasource.seturl("jdbc:hsqldb:mem:mydb"); return basicdatasource; } /** * * loading hibernate properties properties file */ protected properties buildhibernateproperties() { properties hibernateproperties = new properties(); hibernateproperties.setproperty("hibernate.dialect", "org.hibernate.dialect.hsqldialect"); hibernateproperties.setproperty("hibernate.show_sql", "true"); hibernateproperties.setproperty("hibernate.use_sql_comments", "true"); hibernateproperties.setproperty("hibernate.format_sql", "true"); hibernateproperties.setproperty("hibernate.hbm2ddl.auto", "create-drop"); hibernateproperties.setproperty("hibernate.generate_statistics", env.getproperty("hibernate.generate_statistics")); hibernateproperties.setproperty("javax.persistence.validation.mode", env.getproperty("javax.persistence.validation.mode")); //audit history flags hibernateproperties.setproperty("org.hibernate.envers.store_data_at_delete", env.getproperty("org.hibernate.envers.store_data_at_delete")); hibernateproperties.setproperty("org.hibernate.envers.global_with_modified_flag", env.getproperty("org.hibernate.envers.global_with_modified_flag")); return hibernateproperties; } }
which attempting set own persistence context, can run test this:
@runwith(springjunit4classrunner.class) public class applicationintegrationtest extends testapplicationcontext { mockmvc mockmvc; @autowired private webapplicationcontext wac; @resource(name="springsecurityfilterchain") private filterchainproxy springsecurityfilterchain; @before public void setup() { // using web application initiate mock mockmvc = mockmvcbuilders.webappcontextsetup(wac).addfilter(springsecurityfilterchain).build(); } @test public void thatviewbootstrapuseshttpnotfound() throws exception { mvcresult result = mockmvc.perform(post("/login") .param("username", "user").param("password", "password")).andreturn(); cookie c = result.getresponse().getcookie("my-cookie"); assertthat(c.getvalue().length(), greaterthan(10)); // no cookie; 401 unauthorized mockmvc.perform(get("/")).andexpect(status().isunauthorized()); // cookie; 200 ok mockmvc.perform(get("/").cookie(c)).andexpect(status().isok()); // logout, , ensure we're told wipe cookie result = mockmvc.perform(delete("/session")).andreturn(); c = result.getresponse().getcookie("my-cookie"); assertthat(c.getvalue().length(), is(0)); } }
now backed hibernate hsqldb userdao, called deviceusernamepasswordauthenticationprovider
@service(value="customauthenticationprovider") public class deviceusernamepasswordauthenticationprovider implements authenticationprovider { private static final logger log = loggerfactory.getlogger(deviceusernamepasswordauthenticationprovider.class); @autowired private customuserdetailsservice customuserdetailsservice; @autowired private devicedetailsservice devicedetailsservice; @override public boolean supports(class<? extends object> authentication) { return authentication.equals(deviceusernamepasswordauthenticationtoken.class); } /** * implements authentication number of scenarios in mind: * <ul> * <li>a non-browser client making request without device details - fail</li> * <li>a non-browser client making request device details in request - check * if successful token set</li> * <li>a non-browser client making request device token - check</li> * <li>a browser client making request device token or device details user , password - check * if successful jsessionid set</li> * </ul> * @param authentication * @return * @throws authenticationexception */ @override public authentication authenticate(authentication authentication) throws authenticationexception { log.info("authenticating device , user - assigning authorities..."); deviceusernamepasswordauthenticationtoken auth = (deviceusernamepasswordauthenticationtoken) authentication; string name = auth.getname(); string password = auth.getcredentials().tostring(); boolean isdevicerequest = (name == null && password == null); log.debug("name {}, password {}", name, password); // (a) nothing, (b) hastoken|<token encoding>, or (c) gettoken|<base64 encoded device request> string devicetoken = auth.getdeviceauthorisation(); if (devicetoken == null) { // bad - set anonymous log.error("missing.device.token"); throw new badcredentialsexception("missing.device.token"); } log.debug("devicetoken {}", devicetoken); string[] deviceinformation = stringutils.split(devicetoken,"|"); devicedetails device = null; if(deviceinformation[0].equals("gettoken")) { log.debug("gettoken"); // expect array of length 3, if not, request malformed if (deviceinformation.length < 3) { log.error("malformed.device.token"); throw new badcredentialsexception("malformed.device.token"); } device = devicedetailsservice.loaddevicebydeviceid(deviceinformation[1]); if (device == null) { log.error("missing.device"); throw new badcredentialsexception("missing.device"); } else { // otherwise, authorities auth = new deviceusernamepasswordauthenticationtoken(null, null, device.getdeviceid(), device.getauthorities()); //also need set new token database string newtoken = hashing.sha256() .hashstring("your input", charsets.utf_8) .tostring(); devicedetailsservice.settoken(device.getdeviceid(),newtoken); // , put response headers auth.setdevicetokenforheaders(newtoken); } } else if(deviceinformation[0].equals("hastoken")) { log.debug("hastoken"); if (deviceinformation.length < 3) { log.error("malformed.device.token"); throw new badcredentialsexception("malformed.device.token"); } // check there token , token has not expired string token = devicedetailsservice.gettoken(deviceinformation[1]); if (token == null) { // got token in request token have no stored token log.error("mismatched.device.token"); throw new badcredentialsexception("mismatched.device.token"); } else if(!token.equals(deviceinformation[2])) { // got token in request , not same token have stored log.error("mismatched.device.token"); throw new badcredentialsexception("mismatched.device.token"); } else if ( devicedetailsservice.hastokenexpired(deviceinformation[1])) { // got token in request , not same token have stored log.error("expired.device.token"); throw new badcredentialsexception("expired.device.token"); } else { // token in request, correctly formed, , matches out records device = devicedetailsservice.loaddevicebydeviceid(deviceinformation[1]); auth = new deviceusernamepasswordauthenticationtoken(null, null, device.getdeviceid(), device.getauthorities()); } } else { log.error("malformed.device.token"); throw new badcredentialsexception("malformed.device.token"); } if (!isdevicerequest) { // ok, can user stuff userdetails user = customuserdetailsservice.loaduserbyusername(name); auth = new deviceusernamepasswordauthenticationtoken(name, password, device.getdeviceid(), device.getauthorities()); } return auth; } }
which uses customuserdetailsservice so:
@service(value="customuserdetailsservice") @transactional(readonly=true) public class customuserdetailsserviceimpl implements customuserdetailsservice { private static final logger log = loggerfactory.getlogger(customuserdetailsserviceimpl.class); @autowired private userdao userdao; public userdetails loaduserbyusername(string login) throws usernamenotfoundexception { log.info("finding userdetails {}", login); com.touchcorp.touchpoint.model.domain.user domainuser = userdao.getuser(login); if(domainuser == null) { throw new usernamenotfoundexception("the user {} not found", login); } boolean enabled = true; boolean accountnonexpired = true; boolean credentialsnonexpired = true; boolean accountnonlocked = true; return new user( domainuser.getlogin(), domainuser.getpassword(), enabled, accountnonexpired, credentialsnonexpired, accountnonlocked, getauthorities(domainuser.getroles()) ); } public collection<? extends grantedauthority> getauthorities(list<role> roles) { list<grantedauthority> authorities = new arraylist<>(); log.debug("list of authorities..."); (role role : roles) { stringbuilder bob = new stringbuilder("role_"); bob.append(role.getrole().touppercase()); log.debug("authority {}",bob.tostring()); authorities.add(new simplegrantedauthority(bob.tostring())); } return authorities; } }
which calls on userdao..
@repository("userdao") public class userdaoimpl implements userdao { private static final logger log = loggerfactory.getlogger(userdaoimpl.class); @persistencecontext private entitymanager entitymanager; public user getuser(string login) { log.debug("looking user login: {}", login); list<user> list = entitymanager.createquery( "select u user u u.login = :login") .setparameter("login", login).getresultlist( ); return (list.isempty( )?null:list.get( 0 )); } }
the problem container won't start up, , instead throws evil beancreationexception.
here's stack trace stepping through various layers
caused by: org.springframework.beans.factory.beancreationexception: error creating bean name 'customauthenticationprovider': injection of autowired dependencies failed; nested exception org.springframework.beans.factory.beancreationexception: not autowire field: private com.touchcorp.touchpoint.service.customuserdetailsservice com.touchcorp.touchpoint.security.deviceusernamepasswordauthenticationprovider.customuserdetailsservice; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'customuserdetailsservice': injection of autowired dependencies failed; nested exception org.springframework.beans.factory.beancreationexception: not autowire field: private com.touchcorp.touchpoint.model.dao.userdao com.touchcorp.touchpoint.service.customuserdetailsserviceimpl.userdao; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'userdao': injection of persistence dependencies failed; nested exception org.springframework.beans.factory.nosuchbeandefinitionexception: no qualifying bean of type [javax.persistence.entitymanagerfactory] defined @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor.postprocesspropertyvalues(autowiredannotationbeanpostprocessor.java:292) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.populatebean(abstractautowirecapablebeanfactory.java:1185) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.docreatebean(abstractautowirecapablebeanfactory.java:537) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.createbean(abstractautowirecapablebeanfactory.java:475) @ org.springframework.beans.factory.support.abstractbeanfactory$1.getobject(abstractbeanfactory.java:304) @ org.springframework.beans.factory.support.defaultsingletonbeanregistry.getsingleton(defaultsingletonbeanregistry.java:228) @ org.springframework.beans.factory.support.abstractbeanfactory.dogetbean(abstractbeanfactory.java:300) @ org.springframework.beans.factory.support.abstractbeanfactory.getbean(abstractbeanfactory.java:195) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.findautowirecandidates(defaultlistablebeanfactory.java:1017) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.doresolvedependency(defaultlistablebeanfactory.java:960) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.resolvedependency(defaultlistablebeanfactory.java:858) @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor$autowiredfieldelement.inject(autowiredannotationbeanpostprocessor.java:480) ... 45 more caused by: org.springframework.beans.factory.beancreationexception: not autowire field: private com.touchcorp.touchpoint.service.customuserdetailsservice com.touchcorp.touchpoint.security.deviceusernamepasswordauthenticationprovider.customuserdetailsservice; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'customuserdetailsservice': injection of autowired dependencies failed; nested exception org.springframework.beans.factory.beancreationexception: not autowire field: private com.touchcorp.touchpoint.model.dao.userdao com.touchcorp.touchpoint.service.customuserdetailsserviceimpl.userdao; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'userdao': injection of persistence dependencies failed; nested exception org.springframework.beans.factory.nosuchbeandefinitionexception: no qualifying bean of type [javax.persistence.entitymanagerfactory] defined @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor$autowiredfieldelement.inject(autowiredannotationbeanpostprocessor.java:508) @ org.springframework.beans.factory.annotation.injectionmetadata.inject(injectionmetadata.java:87) @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor.postprocesspropertyvalues(autowiredannotationbeanpostprocessor.java:289) ... 56 more caused by: org.springframework.beans.factory.beancreationexception: error creating bean name 'customuserdetailsservice': injection of autowired dependencies failed; nested exception org.springframework.beans.factory.beancreationexception: not autowire field: private com.touchcorp.touchpoint.model.dao.userdao com.touchcorp.touchpoint.service.customuserdetailsserviceimpl.userdao; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'userdao': injection of persistence dependencies failed; nested exception org.springframework.beans.factory.nosuchbeandefinitionexception: no qualifying bean of type [javax.persistence.entitymanagerfactory] defined @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor.postprocesspropertyvalues(autowiredannotationbeanpostprocessor.java:292) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.populatebean(abstractautowirecapablebeanfactory.java:1185) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.docreatebean(abstractautowirecapablebeanfactory.java:537) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.createbean(abstractautowirecapablebeanfactory.java:475) @ org.springframework.beans.factory.support.abstractbeanfactory$1.getobject(abstractbeanfactory.java:304) @ org.springframework.beans.factory.support.defaultsingletonbeanregistry.getsingleton(defaultsingletonbeanregistry.java:228) @ org.springframework.beans.factory.support.abstractbeanfactory.dogetbean(abstractbeanfactory.java:300) @ org.springframework.beans.factory.support.abstractbeanfactory.getbean(abstractbeanfactory.java:195) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.findautowirecandidates(defaultlistablebeanfactory.java:1017) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.doresolvedependency(defaultlistablebeanfactory.java:960) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.resolvedependency(defaultlistablebeanfactory.java:858) @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor$autowiredfieldelement.inject(autowiredannotationbeanpostprocessor.java:480) ... 58 more caused by: org.springframework.beans.factory.beancreationexception: not autowire field: private com.touchcorp.touchpoint.model.dao.userdao com.touchcorp.touchpoint.service.customuserdetailsserviceimpl.userdao; nested exception org.springframework.beans.factory.beancreationexception: error creating bean name 'userdao': injection of persistence dependencies failed; nested exception org.springframework.beans.factory.nosuchbeandefinitionexception: no qualifying bean of type [javax.persistence.entitymanagerfactory] defined @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor$autowiredfieldelement.inject(autowiredannotationbeanpostprocessor.java:508) @ org.springframework.beans.factory.annotation.injectionmetadata.inject(injectionmetadata.java:87) @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor.postprocesspropertyvalues(autowiredannotationbeanpostprocessor.java:289) ... 69 more caused by: org.springframework.beans.factory.beancreationexception: error creating bean name 'userdao': injection of persistence dependencies failed; nested exception org.springframework.beans.factory.nosuchbeandefinitionexception: no qualifying bean of type [javax.persistence.entitymanagerfactory] defined @ org.springframework.orm.jpa.support.persistenceannotationbeanpostprocessor.postprocesspropertyvalues(persistenceannotationbeanpostprocessor.java:356) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.populatebean(abstractautowirecapablebeanfactory.java:1185) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.docreatebean(abstractautowirecapablebeanfactory.java:537) @ org.springframework.beans.factory.support.abstractautowirecapablebeanfactory.createbean(abstractautowirecapablebeanfactory.java:475) @ org.springframework.beans.factory.support.abstractbeanfactory$1.getobject(abstractbeanfactory.java:304) @ org.springframework.beans.factory.support.defaultsingletonbeanregistry.getsingleton(defaultsingletonbeanregistry.java:228) @ org.springframework.beans.factory.support.abstractbeanfactory.dogetbean(abstractbeanfactory.java:300) @ org.springframework.beans.factory.support.abstractbeanfactory.getbean(abstractbeanfactory.java:195) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.findautowirecandidates(defaultlistablebeanfactory.java:1017) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.doresolvedependency(defaultlistablebeanfactory.java:960) @ org.springframework.beans.factory.support.defaultlistablebeanfactory.resolvedependency(defaultlistablebeanfactory.java:858) @ org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor$autowiredfieldelement.inject(autowiredannotationbeanpostprocessor.java:480) ... 71 more caused by: org.springframework.beans.factory.nosuchbeandefinitionexception: no qualifying bean of type [javax.persistence.entitymanagerfactory] defined @ org.springframework.orm.jpa.support.persistenceannotationbeanpostprocessor.finddefaultentitymanagerfactory(persistenceannotationbeanpostprocessor.java:559) @ org.springframework.orm.jpa.support.persistenceannotationbeanpostprocessor.findentitymanagerfactory(persistenceannotationbeanpostprocessor.java:515) @ org.springframework.orm.jpa.support.persistenceannotationbeanpostprocessor$persistenceelement.resolveentitymanager(persistenceannotationbeanpostprocessor.java:682) @ org.springframework.orm.jpa.support.persistenceannotationbeanpostprocessor$persistenceelement.getresourcetoinject(persistenceannotationbeanpostprocessor.java:655) @ org.springframework.beans.factory.annotation.injectionmetadata$injectedelement.inject(injectionmetadata.java:155) @ org.springframework.beans.factory.annotation.injectionmetadata.inject(injectionmetadata.java:87) @ org.springframework.orm.jpa.support.persistenceannotationbeanpostprocessor.postprocesspropertyvalues(persistenceannotationbeanpostprocessor.java:353) ... 82 more
does know missing here?
@runwith(springjunit4classrunner.class) @springapplicationconfiguration(classes = {mvcconfig.class,securityconfig.class}) @webappconfiguration
these 3 lines make no sense ever on configuration class. should instead annotated @configuration
, 3 lines should on test class.
@runwith(springjunit4classrunner.class) @springapplicationconfiguration(classes = testapplicationcontext.class) @webappconfiguration public class applicationintegrationtest { … }
this explained in spring boot reference guide in the testing section.
Comments
Post a Comment