Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'securityService' - spring

SecurityConfig
package com.book.entity.security.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private Environment env;
#Autowired
private SecurityService securityService;
private BCryptPasswordEncoder passwordEncoder() {
return SecurityUtility.passwordEncoder();
}
private static final String[] PUBLIC_MATCHERS = { "/css/**", "/js/**", "/image/**", "/", "/myAccount" };
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().
/* antMatchers("/**"). */
antMatchers(PUBLIC_MATCHERS).permitAll().anyRequest().authenticated();
http.csrf().disable().cors().disable().formLogin().failureUrl("/login?error").defaultSuccessUrl("/")
.loginPage("/login").permitAll().and().logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout")).logoutSuccessUrl("/?logout")
.deleteCookies("remember-me").permitAll().and().rememberMe();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(securityService).passwordEncoder(passwordEncoder());
}
}
SecurityUtility
package com.book.entity.security.impl;
import java.security.SecureRandom;
import java.util.Random;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;
#Component
public class SecurityUtility {
private static final String SALT = "salt"; // Salt should be protected carefully
#Bean
public static BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12, new SecureRandom(SALT.getBytes()));
}
#Bean
public static String randomPassword() {
String SALTCHARS = "ABCEFGHIJKLMNOPQRSTUVWXYZ1234567890";
StringBuilder salt = new StringBuilder();
Random rnd = new Random();
while (salt.length() < 18) {
int index = (int) (rnd.nextFloat() * SALTCHARS.length());
salt.append(SALTCHARS.charAt(index));
}
String saltStr = salt.toString();
return saltStr;
}
}
UserRepository
package com.book.entity.security.impl;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.book.entity.User;
#Repository
public interface UserRepository extends JpaRepository<User, Long>{
User findByUsername(String userName);
}
SecurityService
package com.book.entity.security.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.book.entity.User;
#Service
public class SecurityService implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = userRepository.findByUsername(userName);
if (null == user) {
throw new UsernameNotFoundException("Username not found");
}
return user;
}
}
Error:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'securityService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityService': Unsatisfied dependency expressed through field 'userRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Failed to create query for method public abstract com.book.entity.User com.book.entity.security.impl.UserRepository.findByUsername(java.lang.String)! Unable to locate Attribute with the the given name [username] on this ManagedType [com.book.entity.User]

Related

Unsatisfied dependency expressed through field 'userTokenService'

homeControler
package com.book.controller;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.book.entity.User;
import com.book.entity.security.UserToken;
import com.book.entity.security.service.SecurityService;
import com.book.entity.security.service.UserTokenService;
#Controller
public class HomeController {
#Autowired
private UserTokenService userTokenService;
#Autowired
private SecurityService securityService;
#RequestMapping("/")
public String getHome() {
return "index";
}
#RequestMapping("/myaccount")
public String myAccount() {
return "myAccount";
}
#RequestMapping("/login")
public String login(Model model) {
model.addAttribute("classActiveLogin", true);
return "myAccount";
}
#RequestMapping("/forgetPassword")
public String forgetPassword(Model model) {
model.addAttribute("classActiveForgetPassword", true);
return "myAccount";
}
#RequestMapping("/newUser")
public String newUser(Locale locale, #RequestParam("token") String token, Model model) {
UserToken userToken = userTokenService.getPasswordResetToken(token);
if (userToken == null) {
String msg = "Invalid Token";
model.addAttribute("msg", msg);
return "redirect:/badRequest";
}
User user = userToken.getUser();
String username = user.getUsername();
UserDetails userDetails = securityService.loadUserByUsername(username);
Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(),
userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
model.addAttribute("classActiveEdit", true);
return "myProfile";
}
}
User Token
package com.book.entity.security;
import java.util.Calendar;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import com.book.entity.User;
#Entity
public class UserToken {
private static final int EXPIRATION = 60 * 24;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String token;
#OneToOne(targetEntity = User.class, fetch = FetchType.EAGER)
#JoinColumn(nullable=false, name="user_id")
private User user;
private Date expiryDate;
public UserToken(final String token, final User user) {
super ();
this.token = token;
this.user = user;
this.expiryDate = calculateExpiryDate(EXPIRATION);
}
private Date calculateExpiryDate (final int expiryTimeInMinutes) {
final Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(new Date().getTime());
cal.add(Calendar.MINUTE, expiryTimeInMinutes);
return new Date(cal.getTime().getTime());
}
public void updateToken(final String token) {
this.token = token;
this.expiryDate = calculateExpiryDate(EXPIRATION);
}
#Override
public String toString() {
return "P_Token [id=" + id + ", token=" + token + ", user=" + user + ", expiryDate=" + expiryDate + "]";
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Date getExpiryDate() {
return expiryDate;
}
public void setExpiryDate(Date expiryDate) {
this.expiryDate = expiryDate;
}
public static int getExpiration() {
return EXPIRATION;
}
}
UserTokenService
package com.book.entity.security.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.book.entity.User;
import com.book.entity.security.UserToken;
import com.book.entity.security.repo.PasswordResetRepo;
import com.book.entity.security.repo.UserTokenRepo;
#Service("userTokenService")
public class UserTokenService implements UserTokenRepo{
#Autowired
private PasswordResetRepo repo;
#Override
public UserToken getPasswordResetToken(final String token) {
return repo.findByToken(token);
}
#Override
public void createPasswordResetTokenForUser(final User user, final String token) {
final UserToken myToken = new UserToken(token, user);
repo.save(myToken);
}
}
UserTokenRepo
package com.book.entity.security.repo;
import com.book.entity.User;
import com.book.entity.security.UserToken;
public interface UserTokenRepo {
UserToken getPasswordResetToken(final String token);
void createPasswordResetTokenForUser(final User user, final String token);
}
SecurityService
package com.book.entity.security.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.book.entity.User;
import com.book.entity.security.repo.SecurityUserRepository;
#Service
public class SecurityService implements UserDetailsService {
#Autowired
private SecurityUserRepository securityUserRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = securityUserRepository.findByUsername(username);
if (null == user) {
throw new UsernameNotFoundException("Username not found");
}
return user;
}
}
PasswordResetRepo
package com.book.entity.security.repo;
import java.util.Date;
import java.util.stream.Stream;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import com.book.entity.User;
import com.book.entity.security.UserToken;
public interface PasswordResetRepo extends JpaRepository<UserToken, Long > {
UserToken findByToken(String token);
UserToken findByUser(User user);
Stream<UserToken> findAllByExpiryDateLessThan(Date now);
#Modifying
#Query("delete from P_Token t where t.expirydate <= ?1")
void deleteAllExpiredSince(Date now);
}
Error:-->
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'homeController': Unsatisfied dependency expressed through field 'userTokenService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'userTokenService': Unsatisfied dependency expressed through field 'repo'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'passwordResetRepo': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: antlr/RecognitionException
May be problem lays on HomeController bellow code:
#Autowired
private UserTokenService userTokenService;
Replace this code with bellow code:
#Autowired
private UserTokenRepo userTokenService;
Your main error portion is:
Unsatisfied dependency expressed through field 'repo'; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'passwordResetRepo': Invocation of init
method failed; nested exception is java.lang.NoClassDefFoundError:
antlr/RecognitionException
Here it is failed to create bean passwordResetRepo cause antlr/RecognitionException
Its solution is java.lang.ClassNotFoundException: antlr.RecognitionException shows antlr lib missing.
Add it and itss done :)
You can try to add the following dependency. It will solve your issue.
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr-complete</artifactId>
<version>3.5.2</version>
</dependency>
Another possible consideration:
Please check all JPA query on PasswordResetRepo repository. Sometimes if query not matched with entity variable name then Spring can't create bean for that repository
Hope this will solve your problem.
Thanks :)
Take a look at the stacktrace. The issue is: spring IoC container is failing to create homeController bean; because the container is failing to create userTokenService bean; and that is because the container is failing to create passwordResetRepo bean with java.lang.NoClassDefFoundError.
Adding the following in your config file should solve your problem:
<jpa:repositories base-package="com.book.entity.security.repo" />
As you are using Spring Boot, please check this guide on Accessing Data with JPA.
From the above mentioned guide:
By default, Spring Boot will enable JPA repository support and look
in the package (and its subpackages) where #SpringBootApplication is
located. If your configuration has JPA repository interface
definitions located in a package not visible, you can point out
alternate packages using #EnableJpaRepositories and its type-safe
basePackageClasses=MyRepository.class parameter.

PROBLEM WITH required a bean of type 'org.springframework.security.core.userdetails.UserDetailsService' that could not be found

When launching with mvn spring-boot:run or even with gradle returns that issue.
***************************
APPLICATION FAILED TO START
***************************
Description:
Field userDetailsService in com.ess.study.jwt.integration.config.SecurityConfig required a bean of type 'org.springframework.security.core.userdetails.UserDetailsService' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
The following candidates were found but could not be injected:
- Bean method 'inMemoryUserDetailsManager' in 'UserDetailsServiceAutoConfiguration' not loaded because #ConditionalOnMissingBean (types: org.springframework.security.authentication.AuthenticationManager,org.springframework.security.authentication.AuthenticationProvider,org.springframework.security.core.userdetails.UserDetailsService; SearchStrategy: all) found beans of type 'org.springframework.security.authentication.AuthenticationManager' authenticationManager
Action:
Consider revisiting the entries above or defining a bean of type 'org.springframework.security.core.userdetails.UserDetailsService' in your configuration.
Here are the main classes, all the requirements looks ok to me, I am using the org.springframework.boot release 2.0.6.RELEASE.RELEASE
package com.ess.study.jwt.integration.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.context.annotation.Primary;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
#Configuration
#EnableWebSecurity // Habilita la seguridad de Spring y consejos Spring Boot para aplicar todos los
// valores predeterminados sensibles
#EnableGlobalMethodSecurity(prePostEnabled = true) // Nos permite tener control de acceso a nivel de método.
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Value("${security.signing-key}")
private String signingKey;
#Value("${security.encoding-strength}")
private Integer encodingStrength;
#Value("${security.security-realm}")
private String securityRealm;
#Autowired
private UserDetailsService userDetailsService;
#Bean
#Override
protected AuthenticationManager authenticationManager() throws Exception {
return super.authenticationManager();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder(encodingStrength));
}
#Autowired
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().httpBasic()
.realmName(securityRealm).and().csrf().disable();
}
#Bean
public JwtAccessTokenConverter accessTokenConverter() {
JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
converter.setSigningKey(signingKey);
return converter;
}
#Bean
public TokenStore tokenStore() {
return new JwtTokenStore(accessTokenConverter());
}
#Bean
#Primary // Making this primary to avoid any accidental duplication with another token
// service instance of the same name
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
return defaultTokenServices;
}
//Nuevo metodo de decodificación.
#Bean
public BCryptPasswordEncoder passwordEncoder() {
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
return bCryptPasswordEncoder;
}
}
and:
package com.ess.study.jwt.integration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class StudySecuredApplication {
public static void main(String[] args) {
SpringApplication.run(StudySecuredApplication.class, args);
}
}
Using maven or gradle it returns the same issue. All annotations and packages names seems to be as required.
Thanks! :)
UserDetailsService is an interface and you have to create its implementation. Example:
#Service("userDetailsService")
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UsersRepository usersRepository;
#Transactional(readOnly = true)
#Override
public UserDetails loadUserByUsername(String login) throws UsernameNotFoundException {
try {
User user = usersRepository.findByLogin(login).get();
return new UserPrincipal(usersRepository.findByLogin(login).get());
} catch (NoSuchElementException e) {
throw new UsernameNotFoundException("User " + login + " not found.", e);
}
}
}

#Autowired Repository in ConstraintValidator null when used from CommandLineRunner

I'm trying to set up a Spring-Data-Rest App using Spring Boot 1.5.9.RELEASE. I have a ConstraintValidator set up like this:
UniqueEmail.java:
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.constraints.NotNull;
import java.lang.annotation.*;
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#Constraint(validatedBy = {UniqueEmailValidator.class})
#NotNull
#ReportAsSingleViolation
public #interface UniqueEmail {
Class<?>[] groups() default {};
String message() default "{eu.icarus.momca.backend.domain.validation.UniqueEmail.message}";
Class<? extends Payload>[] payload() default {};
#Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
#Retention(RetentionPolicy.RUNTIME)
#Documented
static #interface List {
UniqueEmail[] value();
}
}
UniqueEmailValidator.java:
import eu.icarus.momca.backend.domain.repository.AccountRepository;
import org.springframework.beans.factory.annotation.Autowired;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class UniqueEmailValidator implements ConstraintValidator<UniqueEmail, String> {
#Autowired
private AccountRepository accountRepository;
#Override
public void initialize(UniqueEmail annotation) {
}
#Override
public boolean isValid(String email, ConstraintValidatorContext context) {
return accountRepository.findByEmail(email) == null;
}
}
I've also set up listeners for the beforeCreate and beforeSave repository methods:
RestConfiguration.java:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
#Configuration
public class RestConfiguration extends RepositoryRestConfigurerAdapter {
#Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
validatingListener.addValidator("beforeCreate", localValidatorFactoryBean());
validatingListener.addValidator("beforeSave", localValidatorFactoryBean());
}
#Bean
#Primary
LocalValidatorFactoryBean localValidatorFactoryBean() {
return new LocalValidatorFactoryBean();
}
}
My problem:
The validator seems to work when the repository methods are called through REST endpoints, however I also try to set up some stuff in the connected database via a CommandLineRunner that uses the same repository. When the calls to the repository are validated, the autowired AccountRepository in the ConstraintValidator is null even if it isn't null at the same time in the CommandLineRunner that also has the same repository autowired. I don't understand this.
Does anybody have an idea why the repository is null when the validation is triggered from the CommandLineRunner?
Any help is greatly appreciated.
Daniel
Edit: added the CommandLineRunner Code
InitAdminData.java:
import eu.icarus.momca.backend.domain.entity.Account;
import eu.icarus.momca.backend.domain.entity.AccountDetails;
import eu.icarus.momca.backend.domain.entity.AccountProfile;
import eu.icarus.momca.backend.domain.entity.Client;
import eu.icarus.momca.backend.domain.enumeration.AccountRoles;
import eu.icarus.momca.backend.domain.enumeration.ClientRoles;
import eu.icarus.momca.backend.domain.enumeration.GrantTypes;
import eu.icarus.momca.backend.domain.repository.AccountRepository;
import eu.icarus.momca.backend.domain.repository.ClientRepository;
import eu.icarus.momca.backend.domain.service.AccountService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
#Component
public class InitAdminData implements CommandLineRunner {
private static final Collection<AccountRoles> DEFAULT_ACCOUNT_ROLES = Arrays.asList(AccountRoles.ROLE_ACCOUNT, AccountRoles.ROLE_ADMINISTRATOR, AccountRoles.ROLE_CLIENT_OWNER);
private static final Logger logger = LoggerFactory.getLogger(InitAdminData.class);
private AccountRepository accountRepository;
private AccountService accountService;
#Value("${app.admin-email}")
private String adminEmail;
#Value("${app.admin-name}")
private String adminName;
#Value("${app.admin-password}")
private String adminPassword;
private ClientRepository clientRepository;
#Value("${app.default-client-description}")
private String defaultClientDescription;
#Autowired
public InitAdminData(AccountRepository accountRepository, AccountService accountService, ClientRepository clientRepository) {
this.accountRepository = accountRepository;
this.clientRepository = clientRepository;
this.accountService = accountService;
}
private Account initAdminAccount() {
Account adminAccount = accountRepository.findByAccountProfile_Name(adminName);
if (adminAccount == null) {
adminAccount = new Account();
logger.info("Initialized new admin account");
} else {
logger.info("Refreshed admin account");
}
setAdminAccountData(adminAccount);
return accountService.save(adminAccount, adminPassword);
}
private void initDefaultClient(Account adminAccount) {
long adminAccountId = adminAccount.getId();
Collection<Client> adminClients = clientRepository.findAllByOwnerId(adminAccountId);
if (adminClients.isEmpty()) {
Client defaultClient = new Client();
defaultClient.setOwnerId(adminAccountId);
defaultClient.setDescription(defaultClientDescription);
Collection<ClientRoles> clientRoles = new HashSet<>(2);
clientRoles.add(ClientRoles.ROLE_CLIENT);
clientRoles.add(ClientRoles.ROLE_DEFAULT_CLIENT);
defaultClient.setRoles(clientRoles);
Collection<GrantTypes> grantTypes = new HashSet<>();
grantTypes.add(GrantTypes.authorization_code);
grantTypes.add(GrantTypes.client_credentials);
grantTypes.add(GrantTypes.password);
grantTypes.add(GrantTypes.refresh_token);
defaultClient.setGrantTypes(grantTypes);
defaultClient = clientRepository.save(defaultClient);
logger.info(String.format("Added new default client with id '%s'", defaultClient.getId()));
}
}
#Override
public void run(String... args) {
Account adminAccount = initAdminAccount();
initDefaultClient(adminAccount);
}
private void setAdminAccountData(Account adminAccount) {
adminAccount.setEmail(adminEmail);
adminAccount.setRoles(DEFAULT_ACCOUNT_ROLES);
adminAccount.setAccountDetails(new AccountDetails());
adminAccount.setAccountProfile(new AccountProfile(adminName));
}
}
Add the #ComponentScan annotation.
#ComponentScan
public class InitAdminData implements CommandLineRunner {
...
}
I think you may have few cases :-
you haven't autowired your service and Repo
you haven't scan your Repo where you have your service and Repo.
Or you haven't use #Component(any stereotype) annotation on your classes which you are autowiring

How to get Neo4jTemplate in SDN4

I am using Spring Data Neo4j 4(SDN4) from the example project SDN4-northwind(https://github.com/amorgner/sdn4-northwind),when I try to get the Neo4jTemplate bean,I get the error message like this.
Does anyone know how to get the Neo4jTemplate bean from SDN4?
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.data.neo4j.template.Neo4jTemplate] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:371)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:331)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:968)
at org.neo4j.example.northwind.Run.main(Run.java:34)
Here is the Configuration file
package org.neo4j.example.northwind;
import org.neo4j.ogm.session.Session;
import org.neo4j.ogm.session.SessionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.repository.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.server.Neo4jServer;
import org.springframework.data.neo4j.server.RemoteServer;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableNeo4jRepositories("org.neo4j.example.northwind.repository")
#EnableTransactionManagement
public class AppContext extends Neo4jConfiguration {
public static final String NEO4J_HOST = "http://localhost:";
public static final int NEO4J_PORT = 7474;
#Override
public SessionFactory getSessionFactory() {
System.setProperty("username", "neo4j");
System.setProperty("password", System.getProperty("password","osp"));
return new SessionFactory("org.neo4j.example.northwind.model");
}
#Bean
#Override
public Neo4jServer neo4jServer() {
return new RemoteServer(NEO4J_HOST + NEO4J_PORT);
}
#Bean
#Override
//#Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Session getSession() throws Exception {
return super.getSession();
}
}
Assdd
#Bean
public Neo4jOperations getNeo4jTemplate() throws Exception {
return new Neo4jTemplate(getSession());
}
to AppContext and then #Autowired Neo4jOperations neo4jTemplate;

Spring 4 + Hibernate 4: ClassCastException with LocalSessionFactoryBean and SessionFactory

By mean of Spring libraries I have to develope a DAL (Data Access Layer) in the form of a jar library which will be imported into the main application.
I want to use Hibernate to access a MySQL DB and DBCP for the management of the connections pool.
I have written the config file DALConfig.java which contains the configuration of the DAL beans:
package my.dal.config;
import java.util.Properties;
import javax.annotation.Resource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
// Needed by Spring to add this class to the ApplicationContext's configuration
#Configuration
#ComponentScan(basePackages = { "my.dal.config" })
// Property file in which are written the MySQL connection properties
#PropertySource("classpath:dbconnection.properties")
public class DALConfig {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_POOL_INITIAL_SIZE = "pool.initialsize";
private static final String PROPERTY_NAME_POOL_MAX_IDLE = "pool.maxidle";
// Needed to access property file
#Resource
private Environment environment;
// The bean which defines the BasicDataSource (DBCP)
#Bean
public BasicDataSource dataSource() throws Exception
{
Properties props = new Properties();
props.put("driverClassName", environment.getProperty(PROPERTY_NAME_DATABASE_DRIVER));
props.put("url", environment.getProperty(PROPERTY_NAME_DATABASE_URL));
props.put("username", environment.getProperty(PROPERTY_NAME_DATABASE_USERNAME));
props.put("password", environment.getProperty(PROPERTY_NAME_DATABASE_PASSWORD));
props.put("initialSize", environment.getProperty(PROPERTY_NAME_POOL_INITIAL_SIZE));
props.put("maxIdle", environment.getProperty(PROPERTY_NAME_POOL_MAX_IDLE));
BasicDataSource bds = BasicDataSourceFactory.createDataSource(props);
return bds;
}
// Bean used to translate Hibernate's exceptions into Spring's ones
#Bean
public PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor()
{
PersistenceExceptionTranslationPostProcessor b = new PersistenceExceptionTranslationPostProcessor();
return b;
}
}
Then I wrote the HibernateConfig.java config file which contains the Hibernate configuration stuff
package my.dal.hibernateconfig;
import java.util.Properties;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
#Configuration
#ComponentScan(basePackages = { "my.dal.hibernatesessionfactory" })
#PropertySource("classpath:dbconnection.properties")
public class HibernateConfig {
private static final String PROPERTY_NAME_DAL_CLASSES_PACKAGE = "hibernate.dal.package";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
#Resource
private Environment environment;
#Autowired
DataSource dataSource;
// Bean which defines the FactoryBean for the SessionBean
#Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
lsfb.setPackagesToScan(PROPERTY_NAME_DAL_CLASSES_PACKAGE);
Properties hibernateProperties = new Properties();
hibernateProperties.put("dialect", PROPERTY_NAME_HIBERNATE_DIALECT);
lsfb.setHibernateProperties(hibernateProperties);
lsfb.setDataSource(dataSource);
return lsfb;
}
#Bean
public HibernateTransactionManager transactionManager()
{
// THE EXCEPTION IS THROWN AT THIS LINE
HibernateTransactionManager htm = new HibernateTransactionManager((SessionFactory) sessionFactory());
return htm;
}
}
Next I wrote the UserDAO.java class which is a DAO for the User class which models the DB's User table.
package my.dal.dao;
import my.models.User;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
#Component
#Repository
#Transactional
public class UserDAO
{
private SessionFactory sessionFactory;
#Autowired
public UserDAO(SessionFactory sessionFactory) {
this.sessionFactory=sessionFactory;
}
public int insert(User user) {
return (Integer) sessionFactory.getCurrentSession().save(user);
}
public User getByUsername(String username) {
return (User) sessionFactory.getCurrentSession().get(User.class, username);
}
public void update(User user) {
sessionFactory.getCurrentSession().merge(user); // .update(user);
}
public void delete(String username) {
User u = getByUsername(username);
sessionFactory.getCurrentSession().delete(u);
}
}
The mapping class User.java (generated using the Eclipse's Hibernate tools) is
package my.models;
public class User implements java.io.Serializable {
private String username;
private String idUserKeystone;
private String firstName;
private String lastName;
private String password;
private String email;
private String emailRef;
private String employer;
private boolean confirmed;
// Getters, setters and full constructor
}
Now I want to test the DAL. The testing class is DALTest.java
package my.dal.tests;
import static org.junit.Assert.assertTrue;
import my.dal.config.DALConfig;
import my.dal.dao.UserDAO;
import my.dal.hibernateconfig.HibernateConfig;
import my.models.User;
import org.hibernate.SessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
#ContextConfiguration(classes = { DALConfig.class, HibernateConfig.class})
#RunWith(SpringJUnit4ClassRunner.class)
public class DALTest {
#Autowired
UserDAO userDAO;
#Test
public void testGetUser() {
User user = null;
// Let's see if the user "myuser" is into the database
user = userDAO.getByUsername("myuser");
assertTrue(null != user);
}
}
When I run the test it throws the following exceptions
java.lang.IllegalStateException: Failed to load ApplicationContext
...
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager' defined in class my.dal.hibernateconfig.HibernateConfig: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.orm.hibernate4.HibernateTransactionManager my.dal.hibernateconfig.HibernateConfig.transactionManager()] threw exception; nested exception is java.lang.ClassCastException: org.springframework.orm.hibernate4.LocalSessionFactoryBean$$EnhancerBySpringCGLIB$$d866ed45 cannot be cast to org.hibernate.SessionFactory
...
Caused by: java.lang.ClassCastException: org.springframework.orm.hibernate4.LocalSessionFactoryBean$$EnhancerBySpringCGLIB$$d866ed45 cannot be cast to org.hibernate.SessionFactory
at my.dal.hibernateconfig.HibernateConfig.transactionManager(HibernateConfig.java:55)
at my.dal.hibernateconfig.HibernateConfig$$EnhancerBySpringCGLIB$$bd53a036.CGLIB$transactionManager$1(<generated>)
at my.dal.hibernateconfig.HibernateConfig$$EnhancerBySpringCGLIB$$bd53a036$$FastClassBySpringCGLIB$$119f2c5b.invoke(<generated>)
...
It seems like the problem is the cast at the line
HibernateTransactionManager htm = new HibernateTransactionManager((SessionFactory) sessionFactory())
On the contrary, the Internet is full of example writing that line that way.
What could be the problem?
Thank you in advance
A FactoryBean<Foo> is a bean that creates objects of type Foo. It's not, itself, of type Foo (as the javadoc would show you). To get the Foo it creates, you simply call getObject() on the factory bean:
HibernateTransactionManager htm =
new HibernateTransactionManager(sessionFactory().getObject());

Resources