不确定如何在使用复合键的Spring Boot应用程序中实现serializble

问题描述

我有一个Spring Boot应用程序,其中包含以下两个数据库表:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,`first_name` varchar(45) DEFAULT NULL,`last_name` varchar(45) DEFAULT NULL,`email` varchar(45) NOT NULL UNIQUE
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;


CREATE TABLE `authorities` (
  `email` varchar(45) NOT NULL,`authority` varchar(50) NOT NULL,UNIQUE KEY `authorities_idx_1` (`email`,`authority`),CONSTRAINT `authorities_ibfk_1` FOREIGN KEY (`email`) REFERENCES `users` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我的模型当前如下所示:

package com.paulcarron.clubmanager.entity;

@Entity
@Table(name="users")
public class User {
    
    public static final PasswordEncoder PASSWORD_ENCODER = new BCryptPasswordEncoder();
    
    @OnetoMany(mappedBy="user",cascade={CascadeType.PERSIST,CascadeType.MERGE,CascadeType.DETACH,CascadeType.REFRESH,CascadeType.REMOVE})
    private List<Authority> authorities;

    // define fields
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id")
    private int id;

    @Column(name="first_name")
    private String firstName;

    @Column(name="last_name")
    private String lastName;
    
    @Column(name="gender")
    private String gender;
    
    @DateTimeFormat(pattern="yyyy-MM-dd")
    @Column(name="birth_date")
    private LocalDate birthDate;
    
    @Column(name="address_line1")
    private String addressLine1;
    
    @Column(name="address_line2")
    private String addressLine2;
    
    @Column(name="town")
    private String town;
    
    @Column(name="county")
    private String county;
    
    @Column(name="country")
    private String country;
    
    @Column(name="postcode")
    private String postcode;
    
    @Column(name="email")
    private String email;
    
    @Column(name="phone")
    private String phone;
    
    @Column(name="mobile")
    private String mobile;
    
    @Column(name="password")
    private @JsonIgnore String password;
    
    @Column(name="enabled")
    private int enabled;

    // define constructors
    public User() {
        
    }
    
    public User(List<Authority> authorities,int id,String firstName,String lastName,String gender,LocalDate birthDate,String addressLine1,String addressLine2,String town,String county,String country,String postcode,String email,String phone,String mobile,String password,int enabled) {
    this.authorities = authorities;
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
    this.gender = gender;
    this.birthDate = birthDate;
    this.addressLine1 = addressLine1;
    this.addressLine2 = addressLine2;
    this.town = town;
    this.county = county;
    this.country = country;
    this.postcode = postcode;
    this.email = email;
    this.phone = phone;
    this.mobile = mobile;
    this.password = password;
    this.enabled = enabled;
}
    
    public List<Authority> getAuthorities() {
        return authorities;
    }

    public void setAuthorities(List<Authority> authorities) {
        this.authorities = authorities;
    }
    
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public LocalDate getBirthDate() {
        return birthDate;
    }

    public void setBirthDate(LocalDate birthDate) {
        this.birthDate = birthDate;
    }

    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 getTown() {
        return town;
    }

    public void setTown(String town) {
        this.town = town;
    }

    public String getCounty() {
        return county;
    }

    public void setCounty(String county) {
        this.county = county;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getPostcode() {
        return postcode;
    }

    public void setPostcode(String postcode) {
        this.postcode = postcode;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getpassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = PASSWORD_ENCODER.encode(password);
    }

    public int getEnabled() {
        return enabled;
    }

    public void setEnabled(int enabled) {
        this.enabled = enabled;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ",firstName=" + firstName + ",lastName=" + lastName + ",gender=" + gender
                + ",birthDate=" + birthDate + ",addressLine1=" + addressLine1 + ",addressLine2=" + addressLine2
                + ",town=" + town + ",county=" + county + ",country=" + country + ",postcode=" + postcode
                + ",email=" + email + ",phone=" + phone + ",mobile=" + mobile + "]";
    }
    
}



@Entity
@Table(name="authorities")
public class Authority {    

    @EmbeddedId
    private AuthorityId id;

    @ManyToOne(cascade= {CascadeType.PERSIST,CascadeType.REFRESH})
    @JoinColumn(name="email")
    private User user;
    
    //@Id
    @Column(name="email")
    private String email;
    
    //@Id
    @Column(name="authority")
    private String authority;
    
    public Authority() {
        
    }

    public Authority(User user,String authority) {
        this.user = user;
        this.email = email;
        this.authority = authority;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getAuthority() {
        return authority;
    }

    public void setAuthority(String authority) {
        this.authority = authority;
    }

    @Override
    public String toString() {
        return "Authority [user=" + user + ",authority=" + authority + "]";
    }

}


@Embeddable
public class AuthorityId implements Serializable {

    @Column(name="email")
    private String email;
    
    @Column(name="authority")
    private String authority;
    
    public AuthorityId() {
        
    }

    public AuthorityId(String email,String authority) {
        this.email = email;
        this.authority = authority;
    }

    public String getEmail() {
        return email;
    }

    public String getAuthority() {
        return authority;
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof AuthorityId)) return false;
        AuthorityId that = (AuthorityId) o;
        return Objects.equals(getEmail(),that.getEmail()) &&
                Objects.equals(getAuthority(),that.getAuthority());
    }
 
    // equals/hashCode based on all data(email and authority)
    @Override
    public int hashCode() {
        return Objects.hash(getEmail(),getAuthority());
    }

}

当我尝试运行我的应用程序时,出现以下错误

020-10-25 20:04:21.713 ERROR 90506 --- [  restartedMain] o.s.boot.SpringApplication               : Application run Failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'eventRepository' defined in com.paulcarron.clubmanager.dao.EventRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method Failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.paulcarron.clubmanager.entity.Authority column: authority (should be mapped with insert="false" update="false")
    at org.springframework.beans.factory.support.BeanDeFinitionValueResolver.resolveReference(BeanDeFinitionValueResolver.java:342) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.BeanDeFinitionValueResolver.resolveValueIfNecessary(BeanDeFinitionValueResolver.java:113) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.applyPropertyValues(AbstractAutowireCapablebeanfactory.java:1697) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.populateBean(AbstractAutowireCapablebeanfactory.java:1442) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.doCreateBean(AbstractAutowireCapablebeanfactory.java:593) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:516) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.lambda$doGetBean$0(Abstractbeanfactory.java:324) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:322) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.getBean(Abstractbeanfactory.java:202) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListablebeanfactory.getBeansOfType(DefaultListablebeanfactory.java:624) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListablebeanfactory.getBeansOfType(DefaultListablebeanfactory.java:612) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:51) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:36) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:898) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at com.paulcarron.clubmanager.ClubmanagerApplication.main(ClubmanagerApplication.java:10) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.3.4.RELEASE.jar:2.3.4.RELEASE]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method Failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.paulcarron.clubmanager.entity.Authority column: authority (should be mapped with insert="false" update="false")
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.initializeBean(AbstractAutowireCapablebeanfactory.java:1794) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.doCreateBean(AbstractAutowireCapablebeanfactory.java:594) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:516) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.lambda$doGetBean$0(Abstractbeanfactory.java:324) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:322) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.getBean(Abstractbeanfactory.java:202) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.BeanDeFinitionValueResolver.resolveReference(BeanDeFinitionValueResolver.java:330) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    ... 33 common frames omitted
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Repeated column in mapping for entity: com.paulcarron.clubmanager.entity.Authority column: authority (should be mapped with insert="false" update="false")
    at org.springframework.orm.jpa.AbstractEntityManagerfactorybean.buildNativeEntityManagerFactory(AbstractEntityManagerfactorybean.java:403) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]
Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.paulcarron.clubmanager.entity.Authority column: authority (should be mapped with insert="false" update="false")
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:862) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:880) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:902) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:634) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.mapping.RootClass.validate(RootClass.java:267) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.boot.internal.Metadataimpl.validate(Metadataimpl.java:354) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerfactorybean.createNativeEntityManagerFactory(LocalContainerEntityManagerfactorybean.java:365) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerfactorybean.buildNativeEntityManagerFactory(AbstractEntityManagerfactorybean.java:391) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    ... 4 common frames omitted

似乎我需要更改或向Authorities类添加一些内容,但是我不确定应该如何进行。我找到了一个页面,指出我需要添加implements serializable添加@IdClass,但无法正常工作。有人可以建议我如何解决这个问题吗?

其他信息

按照下面的答案进行更改后,我的堆栈跟踪现在是:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'eventRepository' defined in com.paulcarron.clubmanager.dao.EventRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: Cannot resolve reference to bean 'jpaMappingContext' while setting bean property 'mappingContext'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method Failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Composite-id class must implement Serializable: com.paulcarron.clubmanager.entity.Authority
    at org.springframework.beans.factory.support.BeanDeFinitionValueResolver.resolveReference(BeanDeFinitionValueResolver.java:342) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.BeanDeFinitionValueResolver.resolveValueIfNecessary(BeanDeFinitionValueResolver.java:113) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.applyPropertyValues(AbstractAutowireCapablebeanfactory.java:1697) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.populateBean(AbstractAutowireCapablebeanfactory.java:1442) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.doCreateBean(AbstractAutowireCapablebeanfactory.java:593) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:516) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.lambda$doGetBean$0(Abstractbeanfactory.java:324) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:322) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.getBean(Abstractbeanfactory.java:202) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListablebeanfactory.getBeansOfType(DefaultListablebeanfactory.java:624) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultListablebeanfactory.getBeansOfType(DefaultListablebeanfactory.java:612) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:51) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.data.repository.config.DeferredRepositoryInitializationListener.onApplicationEvent(DeferredRepositoryInitializationListener.java:36) ~[spring-data-commons-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:404) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:361) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:898) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:554) ~[spring-context-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.3.4.RELEASE.jar:2.3.4.RELEASE]
    at com.paulcarron.clubmanager.ClubmanagerApplication.main(ClubmanagerApplication.java:10) ~[classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.3.4.RELEASE.jar:2.3.4.RELEASE]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaMappingContext': Invocation of init method Failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Composite-id class must implement Serializable: com.paulcarron.clubmanager.entity.Authority
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.initializeBean(AbstractAutowireCapablebeanfactory.java:1794) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.doCreateBean(AbstractAutowireCapablebeanfactory.java:594) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:516) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.lambda$doGetBean$0(Abstractbeanfactory.java:324) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:322) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.getBean(Abstractbeanfactory.java:202) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.beans.factory.support.BeanDeFinitionValueResolver.resolveReference(BeanDeFinitionValueResolver.java:330) ~[spring-beans-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    ... 33 common frames omitted
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.MappingException: Composite-id class must implement Serializable: com.paulcarron.clubmanager.entity.Authority
    at org.springframework.orm.jpa.AbstractEntityManagerfactorybean.buildNativeEntityManagerFactory(AbstractEntityManagerfactorybean.java:403) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:832) ~[na:na]
Caused by: org.hibernate.MappingException: Composite-id class must implement Serializable: com.paulcarron.clubmanager.entity.Authority
    at org.hibernate.mapping.RootClass.checkCompositeIdentifier(RootClass.java:293) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.mapping.RootClass.validate(RootClass.java:276) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.boot.internal.Metadataimpl.validate(Metadataimpl.java:354) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ~[hibernate-core-5.4.21.Final.jar:5.4.21.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerfactorybean.createNativeEntityManagerFactory(LocalContainerEntityManagerfactorybean.java:365) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerfactorybean.buildNativeEntityManagerFactory(AbstractEntityManagerfactorybean.java:391) ~[spring-orm-5.2.9.RELEASE.jar:5.2.9.RELEASE]
    ... 4 common frames omitted

解决方法

您需要一个实现Serializable的类,并在@IdClass中使用该类。

话虽如此,我建议您使用嵌入式id代替,因为在某些情况下id类存在问题。然后,可嵌入的类可以实现可序列化。

@Embeddable
public class AuthorityId implements Serializable {
    
    @Column(name="email")
    private String email;
    
    @Column(name="authority")
    private String authority;

    // equals/hashCode based on all data(email and authority)
}

@Entity
@Table(name="authorities")
public class Authority {    

    @EmbeddedId
    private AuthorityId id;

    @ManyToOne(cascade= {CascadeType.PERSIST,CascadeType.MERGE,CascadeType.DETACH,CascadeType.REFRESH})
    @JoinColumn(name="email",insertable = false,updatable = false)
    private User user;

    // You actually don't need that,just use id.getEmail()
    @Column(name="email",updatable = false)
    private String email;

    // You actually don't need that,just use id.getAuthority()
    @Column(name="authority",updatable = false)
    private String authority;

    // equals/hashCode based on id
}