1

I'm using kotlin to store in a database a class from a library. The problem is that this class, haven't got a constructor with no arguments(It is a Java class). When I retrieve the object from the database, I get the following error, as It has no constructor:

java.lang.NoSuchMethodException: org.springframework.security.oauth2.core.OAuth2AccessToken.<init>()

The only solutions I think It will solve the problem, are the following:

  • Change the class where I retrieve the object to Java.
  • Store a different object instead of org.springframework.security.oauth2.core.OAuth2AccessToken class

Any more thoughts on how to solve this problem?

This is my class in the database:

@Document(collection = "authorizedClient")
data class AuthorizedClientDatabase(
    @Id
    var id: ObjectId = ObjectId.get(),
    var name: String? = null,
    var clientRegistration: ClientRegistration,
    var accessToken: OAuth2AccessToken,
    var refreshToken: OAuth2RefreshToken? = null
)

This is the repository class:

@Repository
interface AuthorizedClientDatabaseRepository : MongoRepository<AuthorizedClientDatabase, ObjectId> {
}

This is the OAuth2AccessToken

And I'm simply making a:

authorizedClientDatabaseRepository.findById(...)
david
  • 405
  • 1
  • 7
  • 18

3 Answers3

1

OAuth2AccessToken class does not have a non-argument constructor that you are attempting to call. You need to change your code to use one of the two existing constructors:

public OAuth2AccessToken(TokenType tokenType, String tokenValue, 
       Instant issuedAt, Instant expiresAt) {
   // ...       
}

or

public OAuth2AccessToken(TokenType tokenType, String tokenValue, 
        Instant issuedAt, Instant expiresAt, Set<String> scopes) {
   // ...
}
Karol Dowbecki
  • 38,744
  • 9
  • 58
  • 89
1

I finally changed the OAuth2AccessToken class and created a custom one:

data class DatabaseOauth2AccessToken(
    val tokenValue: String,
    val issuedAt: Instant?,
    val expiredAt: Instant?,
    val scopes: MutableSet<String>
)

AFAIK, this is the most viable solution I have found.

david
  • 405
  • 1
  • 7
  • 18
0

In addition to Karol Dowbecki's answer; if you don't specify a constructor either way all classes provide you with an empty constructor (no params) and no body in it.

Your problem could be one of these:

  1. The empty constructor is private hence not visible to the bit of code that is trying to create an instance
  2. It just has not an empty constructor. There are already other constructors but no "empty" constructor specified. This could be what Karol Dowbecki mentions
  3. It is specified but is private hence we're back to point 1.

A data class should have no effect on this. Data classes just take care of wrapping properties with a backing field and providing you with getters and setters Thanks Alexey for correcting. Kotlin does that with all properties. Besides that, they write the implementation of the toString, equals and hashCode methods and adds a nice method to generate copies of the same object called copy

Some random IT boy
  • 2,687
  • 2
  • 11
  • 28
  • "A data class should have no effect on this." A data class in Kotlin is required to have at least one primary constructor parameter, so there is always a constructor with parameters and a default constructor isn't added. – Alexey Romanov May 23 '20 at 07:55
  • "Data classes just take care of wrapping properties with a backing field and providing you with getters and setters." This is simply wrong; properties themselves take care of providing you with getters and setters, and use backing fields by default, `data class` or not. – Alexey Romanov May 23 '20 at 07:58
  • Sorry Alexey, you are right. What I wanted to say and I totally didnt is that they provide also the copy method which is related to the properties of dataclasses – Some random IT boy May 23 '20 at 08:31