title: spring boot oauth2 with jdbc token store gives oauth_access_token relation doesn't exist
body: <p>I am trying to integrate spring boot with OAuth2. I was able to get this to work with InMemoryStore for tokens by following this <a href="https://github.com/royclarkson/spring-rest-service-oauth" rel="noreferrer">https://github.com/royclarkson/spring-rest-service-oauth</a>. But when I try to implement it with JdbcTokenStore and a postgres database I get the error </p>
  
  <pre><code> Handling error: BadSqlGrammarException, PreparedStatementCallback; bad SQL grammar [select token_id, token from oauth_access_token where authentication_id = ?]; nested exception is org.postgresql.util.PSQLException: ERROR: relation "oauth_access_token" does not exist
  </code></pre>
  
  <p>I have checked my DB, the table exists. </p>
  
  <p><strong>Web Security Config</strong></p>
  
  <pre><code>@Configuration
  @EnableWebSecurity
  public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
  
      private static PasswordEncoder encoder;
  
      @Autowired
      private CustomUserDetailsService userDetailsService;
  
      @Override
      protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
      }
  
      @Override
      @Bean
      public AuthenticationManager authenticationManagerBean() throws Exception {
          return super.authenticationManagerBean();
      }
  
      @Bean
      public PasswordEncoder passwordEncoder() {
          if(encoder == null) {
              encoder = new BCryptPasswordEncoder();
          }
          return encoder;
      }
  }
  </code></pre>
  
  <p><strong>Oauth2Config</strong></p>
  
  <pre><code>@Configuration
  public class OAuth2ServerConfiguration {
  
      private static final String RESOURCE_ID = "restservice";
  
      @Configuration
      @EnableResourceServer
      protected static class ResourceServerConfiguration extends
              ResourceServerConfigurerAdapter {
  
          @Autowired
          private TokenStore tokenStore;
  
          @Override
          public void configure(ResourceServerSecurityConfigurer resources) {
              // @formatter:off
              resources
                      .tokenStore(tokenStore)
                      .resourceId(RESOURCE_ID);
              // @formatter:on
          }
  
          @Override
          public void configure(HttpSecurity http) throws Exception {
              // @formatter:off
              http
                      .authorizeRequests()
                      .antMatchers("/users").hasRole("ADMIN")
                      .antMatchers("/userAccounts/create").permitAll()
                      .antMatchers("/greeting").authenticated();
              // @formatter:on
          }
  
      }
  
      @Configuration
      @EnableAuthorizationServer
      protected static class AuthorizationServerConfiguration extends
              AuthorizationServerConfigurerAdapter {
  
          @Autowired
          DataSource dataSource;
  
          @Bean
          public JdbcTokenStore tokenStore() {
              return new JdbcTokenStore(dataSource);
          }
  
          private static PasswordEncoder encoder;
  
          @Autowired
          @Qualifier("authenticationManagerBean")
          private AuthenticationManager authenticationManager;
  
          @Autowired
          private CustomUserDetailsService userDetailsService;
  
          @Override
          public void configure(AuthorizationServerEndpointsConfigurer endpoints)
                  throws Exception {
              // @formatter:off
              endpoints
                      //.tokenStore(new InMemoryTokenStore())
                      .tokenStore(tokenStore())
                      .authenticationManager(this.authenticationManager)
                      .userDetailsService(userDetailsService);
              // @formatter:on
          }
  
          @Override
          public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
              // @formatter:off
              clients
                      //.inMemory()
                      .jdbc(dataSource)
                      .passwordEncoder(passwordEncoder());
                      //.withClient("clientapp")
                      //.authorizedGrantTypes("password", "refresh_token")
                      //.authorities("USER")
                      //.scopes("read", "write")
                      //.resourceIds(RESOURCE_ID)
                      //.secret("123456");
              // @formatter:on
          }
  
          @Bean
          @Primary
          public DefaultTokenServices tokenServices() {
              DefaultTokenServices tokenServices = new DefaultTokenServices();
              tokenServices.setSupportRefreshToken(true);
              tokenServices.setTokenStore(tokenStore());
              //tokenServices.setTokenStore(new InMemoryTokenStore());
              return tokenServices;
          }
  
          @Bean
          public PasswordEncoder passwordEncoder() {
              if(encoder == null) {
                  encoder = new BCryptPasswordEncoder();
              }
              return encoder;
          }
  
      }
  }
  </code></pre>
  
  <p><strong>CustomUserDetailsService</strong></p>
  
  <pre><code>@Service
  public class CustomUserDetailsService implements UserDetailsService {
  
      private AccountInfoRepository accountInfoRepository;
  
      @Autowired
      public CustomUserDetailsService(AccountInfoRepository accountInfoRepository) {
          this.accountInfoRepository = accountInfoRepository;
      }
  
      @Override
      public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
          AccountInfo user = accountInfoRepository.findByUsername(username);
          System.out.println("USER IS "+user);
          if (user == null) {
              throw new UsernameNotFoundException(String.format("User %s does not exist!", username));
          }
          return new UserRepositoryUserDetails(user);
      }
  
      private final static class UserRepositoryUserDetails extends AccountInfo implements UserDetails,Serializable {
  
          private static final long serialVersionUID = 1L;
  
          private UserRepositoryUserDetails(AccountInfo user) {
              super(user);
          }
  
          @Override
          public Collection&lt;? extends GrantedAuthority&gt; getAuthorities() {
              return getRoles();
          }
  
          @Override
          public boolean isAccountNonExpired() {
              return true;
          }
  
          @Override
          public boolean isAccountNonLocked() {
              return true;
          }
  
          @Override
          public boolean isCredentialsNonExpired() {
              return true;
          }
  
          @Override
          public boolean isEnabled() {
              return true;
          }
  
      }
  
  }
  </code></pre>
  
  <p><strong>application.properties</strong></p>
  
  <pre><code>spring.jpa.database=POSTGRESQL
  spring.datasource.platform=postgres
  spring.jpa.show-sql=true
  spring.jpa.properties.hibernate.default_schema=test
  spring.jpa.hibernate.ddl-auto=none
  spring.datasource.driver-class-name=org.postgresql.Driver
  spring.datasource.url=jdbc:postgresql://localhost:5432/test
  spring.datasource.username=postgres
  spring.datasource.password=postgres
  spring.datasource.schema=test
  
  spring.profiles.active=dev
  
  #Application specific
  security.oauth2.client.client-id=clientapp
  security.oauth2.client.client-secret=123456
  security.oauth2.client.authorized-grant-types=password,refresh_token
  security.oauth2.client.authorities=ROLE_USER
  security.oauth2.client.scope=read,write
  security.oauth2.client.resource-ids=restservice
  security.oauth2.client.access-token-validity-seconds=1800
  </code></pre>
  
  <p><strong>User object</strong></p>
  
  <pre><code>@JsonIgnoreProperties(ignoreUnknown = true)
  @Entity
  @Table(name = "account_info")
  public class AccountInfo implements Serializable {
  
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "account_id")
    Integer accountId;
  
    @Column(name = "account_name")
    String accountName;
  
    @Column(name = "address_line_1")
    String addressLine1;
  
    @Column(name = "address_line_2")
    String addressLine2;
  
    String city;
  
    String state;
  
    String country;
  
    @NotEmpty
    @Column(unique = true, nullable = false)
    String username;
  
    @NotEmpty
    String password;
  
    String email;
  
    @JsonIgnore
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") })
    private Set&lt;Role&gt; roles = new HashSet&lt;&gt;();
  
    public AccountInfo() {
    }
  
    public AccountInfo(AccountInfo accountInfo) {
      this.accountId = accountInfo.getAccountId();
      this.accountName = accountInfo.getAccountName();
      this.username = accountInfo.getUsername();
      this.password = accountInfo.getPassword();
      this.roles = accountInfo.getRoles();
    }
  
    public boolean isSetup() {
      return isSetup;
    }
  
    public void setSetup(boolean isSetup) {
      this.isSetup = isSetup;
    }
  
    public Integer getAccountId() {
      return accountId;
    }
  
    public void setAccountId(Integer accountId) {
      this.accountId = accountId;
    }
  
    public String getAccountName() {
      return accountName;
    }
  
    public void setAccountName(String accountName) {
      this.accountName = accountName;
    }
  
    public String getAddressLine1() {
      return addressLine1;
    }
  
    public void setAddressLine1(String addressLine1) {
      this.addressLine1 = addressLine1;
    }
  
    public String getAddressLine2() {
      return addressLine2;
    }
  
    public void setAddressLine2(String addressLine2) {
      this.addressLine2 = addressLine2;
    }
  
    public String getCity() {
      return city;
    }
  
    public void setCity(String city) {
      this.city = city;
    }
  
    public String getUsername() {
      return username;
    }
  
    public void setUsername(String username) {
      this.username = username;
    }
  
    public String getPassword() {
      return password;
    }
  
    public void setPassword(String password) {
      this.password = password;
    }
  
    public String getEmail() {
      return email;
    }
  
    public void setEmail(String email) {
      this.email = email;
    }
  
    public Set&lt;Role&gt; getRoles() {
      return roles;
    }
  
    public void setRoles(Set&lt;Role&gt; roles) {
      this.roles = roles;
    }
  </code></pre>
  
  <p><strong>This is how I create a user</strong></p>
  
  <pre><code>account.setPassword(new BCryptPasswordEncoder().encode(account.getPassword()));
              Set&lt;Role&gt; roles = new HashSet&lt;&gt;();
              roles.add(new Role("ROLE_USER",1));
              account.setRoles(roles);
              AccountInfo savedAccount=accountInfoRepository.save(account);
  </code></pre>
  
  <p><strong>OAuth2 tables</strong></p>
  
  <pre><code>CREATE TABLE oauth_client_details (
      client_id VARCHAR(256) PRIMARY KEY,
      resource_ids VARCHAR(256),
      client_secret VARCHAR(256),
      scope VARCHAR(256),
      authorized_grant_types VARCHAR(256),
      web_server_redirect_uri VARCHAR(256),
      authorities VARCHAR(256),
      access_token_validity INTEGER,
      refresh_token_validity INTEGER,
      additional_information VARCHAR(4096),
      autoapprove VARCHAR(256)
  );
  ALTER TABLE oauth_client_details OWNER TO postgres;
  
  CREATE TABLE oauth_client_token (
      token_id VARCHAR(256),
      token bytea,
      authentication_id VARCHAR(256),
      user_name VARCHAR(256),
      client_id VARCHAR(256)
  );
  ALTER TABLE oauth_client_token OWNER TO postgres;
  
  CREATE TABLE oauth_access_token (
      token_id VARCHAR(256),
      token bytea,
      authentication_id VARCHAR(256),
      user_name VARCHAR(256),
      client_id VARCHAR(256),
      authentication bytea,
      refresh_token VARCHAR(256)
  );
  ALTER TABLE oauth_access_token OWNER TO postgres;
  
  CREATE TABLE oauth_refresh_token (
      token_id VARCHAR(256),
      token bytea,
      authentication bytea
  );
  ALTER TABLE oauth_refresh_token OWNER TO postgres;
  
  CREATE TABLE oauth_code (
      code VARCHAR(256), authentication bytea
  );
  ALTER TABLE oauth_code OWNER TO postgres;
  </code></pre>