Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Set, at table:

I want to create JPA repository for Spring Authorization Server using this code:

https://programmer.group/spring-oauth2-authorization-server-configuration-details.html

CREATE TABLE oauth2_registered_client
(
    id                            varchar(100)                        NOT NULL,
    client_id                     varchar(100)                        NOT NULL,
    client_id_issued_at           timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
    client_secret                 varchar(200)                        NULL,
    client_secret_expires_at      timestamp                           NULL,
    client_name                   varchar(200)                        NOT NULL,
    client_authentication_methods varchar(1000)                       NOT NULL,
    authorization_grant_types     varchar(1000)                       NOT NULL,
    redirect_uris                 varchar(1000)                       NULL,
    scopes                        varchar(1000)                       NOT NULL,
    client_settings               varchar(2000)                       NOT NULL,
    token_settings                varchar(2000)                       NOT NULL,
    PRIMARY KEY (id)
);

public class RegisteredClient implements Serializable {
 private static final long serialVersionUID = Version.SERIAL_VERSION_UID;
 private String id;
 private String clientId;
 private Instant clientIdIssuedAt;
 private String clientSecret;
 private Instant clientSecretExpiresAt;
 private String clientName;
 private Set<ClientAuthenticationMethod> clientAuthenticationMethods;
 private Set<AuthorizationGrantType> authorizationGrantTypes;
 private Set<String> redirectUris;
 private Set<String> scopes;
 private ClientSettings clientSettings;
 private TokenSettings tokenSettings;
    
    // ellipsis
}

I created this entity:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder(toBuilder = true)
@Entity
@Table(name = "oauth2_registered_client")
public class RegisteredClient {

    @Id
    @Column(name = "id", length = 100, nullable = false)
    private String id;

    @Column(name = "client_id", length = 100, nullable = false)
    private String clientId;

    @Column(name = "client_id_issued_at", nullable = false)
    private Instant clientIdIssuedAt;

    @Column(name = "client_secret", length = 200)
    private String clientSecret;

    @Column(name = "client_secret_expires_at")
    private Instant clientSecretExpiresAt;

    @Column(name = "client_name", length = 200, nullable = false)
    private String clientName;

    @Column(name = "client_authentication_methods", length = 1000, nullable = false)
    private Set<ClientAuthenticationMethod> clientAuthenticationMethods;

    @Column(name = "authorization_grant_types", length = 1000, nullable = false)
    private Set<AuthorizationGrantType> authorizationGrantTypes;

    @Column(name = "redirect_uris", length = 1000)
    private Set<String> redirectUris;

    @Column(name = "scopes", length = 1000, nullable = false)
    private Set<String> scopes;

    @Column(name = "client_settings", length = 2000, nullable = false)
    private ClientSettings clientSettings;

    @Column(name = "token_settings", length = 2000, nullable = false)
    private TokenSettings tokenSettings;
}

But when I start the project I get:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: oauth2_registered_client, for columns: [org.hibernate.mapping.Column(authorization_grant_types)]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:412)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:302)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1290)
    at org.auth.MerchantHubAuthApplication.main(MerchantHubAuthApplication.java:13)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: oauth2_registered_client, for columns: [org.hibernate.mapping.Column(authorization_grant_types)]
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:421)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
    ... 16 common frames omitted
Caused by: org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: oauth2_registered_client, for columns: [org.hibernate.mapping.Column(authorization_grant_types)]
    at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:515)
    at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:482)
    at org.hibernate.mapping.Property.isValid(Property.java:231)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:627)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:267)
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:359)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:314)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
    ... 20 common frames omitted

Do you know how I can fix this issue?


Solution 1:

it seems like this needs a @OneToMany annotation

@OneToMany(targetEntity=AuthorizationGrantType.class, mappedBy="?")

@Column(name = "authorization_grant_types", length = 1000, nullable = false)
    private Set<AuthorizationGrantType> authorizationGrantTypes;

Solution 2:

You are breaking some imporatnt rules of working with hibernate - namely you should only persist POJO classes (that you have created) that are annotated with @Entity. In this case you are referencing in a column a Set<AuthorizationGrantType> which is Spring Security defined class. That can't work.

You should persist the information you need to calculate AuthorizationGrantType, such as a Set of Strings or Enum values.