Java 如何在Spring中使用CommandLineRunner测试JPA实体?

Java 如何在Spring中使用CommandLineRunner测试JPA实体?,java,spring,jpa,spring-data-jpa,Java,Spring,Jpa,Spring Data Jpa,我有2(两)个实体帐户和社会服务。 帐户可以有1(一)个服务(逻辑上),但SocialService可以有多个帐户。 所以我有账户类: @Entity @Table(name = "accounts") @Data public class Account { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "email")

我有2(两)个实体帐户和社会服务。 帐户可以有1(一)个服务(逻辑上),但SocialService可以有多个帐户。 所以我有账户类:

   @Entity
@Table(name = "accounts")
@Data
public class Account {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "email")
    private String email;

    @Column(name = "password")
    private String password;

    @ManyToOne(cascade = CascadeType.ALL)
//    @JoinColumn(name = "social_service_id", referencedColumnName = "id")
    private SocialService socialService;

    @Column(name = "service_link")
    private String serviceLink;


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Account account = (Account) o;
        return id.equals(account.id) &&
                email.equals(account.email) &&
                password.equals(account.password) &&
                socialService.equals(account.socialService);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, email, password, socialService);
    }
}
社会服务类

   @Entity
@Table(name = "social_services")
@Data
public class SocialService {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "name")
    private String name;
    @Column(name = "official_link")
    private String officialLink;

    @OneToMany
    @JoinTable(
            name = "accounts_social_service",
            joinColumns = @JoinColumn(name = "social_service_id"),
            inverseJoinColumns = @JoinColumn(name = "account_id")
    )
    private List<Account> accounts;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        SocialService that = (SocialService) o;
        return Objects.equals(id, that.id) &&
                Objects.equals(name, that.name) &&
                Objects.equals(officialLink, that.officialLink);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, officialLink);
    }
}
@实体
@表(name=“社会服务”)
@资料
公共级社会服务{
@身份证
@GeneratedValue(策略=GenerationType.IDENTITY)
私人长id;
@列(name=“name”)
私有字符串名称;
@列(name=“官方链接”)
私有字符串官方链接;
@独身癖
@可接合(
name=“账户\社会\服务”,
joinColumns=@JoinColumn(name=“social\u service\u id”),
inverseJoinColumns=@JoinColumn(name=“account\u id”)
)
私人名单账户;
@凌驾
公共布尔等于(对象o){
如果(this==o)返回true;
如果(o==null | | getClass()!=o.getClass())返回false;
社会服务,即=(社会服务)o;
返回Objects.equals(id,that.id)&&
Objects.equals(name,that.name)&&
Objects.equals(officialLink,that.officialLink);
}
@凌驾
公共int hashCode(){
返回Objects.hash(id、name、officialLink);
}
}
我尝试使用CommandLineRunner进行测试:

       @Component
public class DatabaseLoader implements CommandLineRunner {
    private final SocialServiceRepository socialServiceRepository;
    private final AccountRepository accountRepository;

    public DatabaseLoader(SocialServiceRepository socialServiceRepository, AccountRepository accountRepository) {
        this.socialServiceRepository = socialServiceRepository;
        this.accountRepository = accountRepository;
    }

    @Override
    public void run(String... args) throws Exception {
        Account account1 = new Account();
        Account account2 = new Account();
        List<Account> accountList = new ArrayList<>();

        account1.setId(1L);
        account1.setEmail("1@gmail.com");
        account1.setPassword("123");
        account1.setServiceLink("https://stackoverflow.com");

        account2.setId(2L);
        account2.setEmail("2@gmail.com");
        account2.setPassword("345");
        account2.setServiceLink("https://stackoverflow.com");

        SocialService socialService = new SocialService();
        account1.setSocialService(socialService);
        account2.setSocialService(socialService);

        socialService.setId(1L);
        socialService.setName("stackoverflow");
        socialService.setOfficialLink("https://stackoverflow.com");

        accountList.add(account1);
        accountList.add(account2);
        socialService.setAccounts(accountList);

        accountRepository.save(account1);
        accountRepository.save(account2);
        socialServiceRepository.save(socialService);
    }
}
@组件
公共类DatabaseLoader实现CommandLineRunner{
私人最终社会服务性社会服务性社会服务性;
私人最终账户存储库账户存储库;
公共数据库加载器(SocialServicePository SocialServicePository,AccountRepository AccountRepository){
this.socialservicepository=socialservicepository;
this.accountRepository=accountRepository;
}
@凌驾
公共无效运行(字符串…参数)引发异常{
账户1=新账户();
账户account2=新账户();
List accountList=new ArrayList();
账户1.设置ID(1L);
account1.setEmail(“1@gmail.com");
账户1.设置密码(“123”);
account1.setServiceLink(“https://stackoverflow.com");
account2.setId(2L);
account2.setEmail(“2@gmail.com");
账户2.设置密码(“345”);
account2.setServiceLink(“https://stackoverflow.com");
社交服务社交服务=新社交服务();
账户1.设置社会服务(社会服务);
账户2.设置社会服务(社会服务);
社会服务setId(1L);
socialService.setName(“stackoverflow”);
socialService.setOfficialLink(“https://stackoverflow.com");
会计清单。添加(会计1);
会计清单。添加(会计2);
社会服务。设置帐户(帐户列表);
accountRepository.save(account1);
accountRepository.save(account2);
社会服务储蓄(社会服务);
}
}
但我得到的是空表
账户\社会\服务
错误在哪里:在实体类中?还是硬编码


更新:添加了完整代码

您没有将帐户添加到accountList。此外,在帐户中使用manytone。在使用JoinTable时,不要在Account中使用JointColumn

因此,您将有:

@ManyToOne(cascade = CascadeType.ALL) private SocialService socialService;

@OneToMany @JoinTable( name = "accounts_social_service", joinColumns = @JoinColumn(name = "social_service_id"), inverseJoinColumns = @JoinColumn(name = "account_id") ) private List<Account> accounts;

Account account1 = new Account();
Account account2 = new Account();
account1.setId(1L);
account1.setEmail("1@gmail.com");
account1.setPassword("123");
account1.setServiceLink("https://stackoverflow.com"); 
account2.setId(2L);
account2.setEmail("2@gmail.com");
account2.setPassword("345");
account2.setServiceLink("https://stackoverflow.com");
SocialService socialService = new SocialService(); 
account1.setSocialService(socialService);
account2.setSocialService(socialService);
socialService.setId(1L);
socialService.setName("stackoverflow");
socialService.setOfficialLink("https://stackoverflow.com");
List<Account> accountList = new ArrayList<>();
accountList.add(account1);
accountList.add(account2);
socialService.setAccounts(accountList);
accountRepository.save(account1);
accountRepository.save(account2);
socialServiceRepository.save(socialService);
@manytone(cascade=CascadeType.ALL)私有社交服务社交服务;
@OneToMany@JoinTable(name=“accounts\u social\u service”,joinColumns=@JoinColumn(name=“social\u service\u id”),inverseJoinColumns=@JoinColumn(name=“account\u id”))私有列表账户;
账户1=新账户();
账户account2=新账户();
账户1.设置ID(1L);
account1.setEmail(“1@gmail.com");
账户1.设置密码(“123”);
account1.setServiceLink(“https://stackoverflow.com"); 
account2.setId(2L);
account2.setEmail(“2@gmail.com");
账户2.设置密码(“345”);
account2.setServiceLink(“https://stackoverflow.com");
社交服务社交服务=新社交服务();
账户1.设置社会服务(社会服务);
账户2.设置社会服务(社会服务);
社会服务setId(1L);
socialService.setName(“stackoverflow”);
socialService.setOfficialLink(“https://stackoverflow.com");
List accountList=new ArrayList();
会计清单。添加(会计1);
会计清单。添加(会计2);
社会服务。设置帐户(帐户列表);
accountRepository.save(account1);
accountRepository.save(account2);
社会服务储蓄(社会服务);

您必须从所有实体中删除setId,因为您指定了生成策略

我在这里测试了您的代码,它可以正常工作:

帐户中的映射:

@ManyToOne(cascade = CascadeType.ALL)
private SocialService socialService;
社会服务制图:

@OneToMany
@JoinTable(
        name = "accounts_social_service",
        joinColumns = @JoinColumn(name = "social_service_id"),
        inverseJoinColumns = @JoinColumn(name = "account_id")
)
private List<Account> accounts;
但是,在这种情况下,最好不要使用JoinTable。只需在帐户中添加一个列(因为它是OneToMany):

@ManyToOne(cascade=CascadeType.ALL)
@JoinColumn(name=“社会服务”)
私人社会服务社会服务;
@OneToMany(mappedBy=“社会服务”)
私人名单账户;

oh-rly。。。但当我添加到列表帐户时,我得到了错误:
原因是:java.sql.SQLSyntaxErrorException:Table'account\u saver.accounts\u social\u service'不存在
执行DDL时出错“alter Table accounts\u social\u service”通过JDBC语句删除外键FKnv4qpalyk3rdmp4irddkb7gy2”
为什么我必须做很多事情?如果我需要1个帐户到1个soc。serv…?我在多通上更改了-仍然存在错误
,原因是:java.sql.SQLSyntaxErrorException:表“account\u saver.accounts\u social\u service”不存在
org.hibernate.tool.schema.spi.CommandAcceptanceException:执行DDL“alter Table accounters\u social\u service drop外键FKclhqynxs5ilyubt1qgo0810ec”时出错通过JDBC语句
是否要求hibernate创建表?首先删除它,因为旧的键我创建了插入属性,但我正在硬编码数据,之前我总是用setId这样做)奇怪的是,谢谢,我会试试。但为什么不加入呢?隔离哪些账户提供社会服务的数据不是更好吗。这将更容易计算,例如,有多少帐户有单一的服务。
    Account account1 = new Account();
    Account account2 = new Account();
    account1.setEmail("1@gmail.com");
    account1.setPassword("123");
    account1.setServiceLink("https://stackoverflow.com"); 
    account2.setEmail("2@gmail.com");
    account2.setPassword("345");
    account2.setServiceLink("https://stackoverflow.com");
    SocialService socialService = new SocialService(); 
    account1.setSocialService(socialService);
    account2.setSocialService(socialService);
    socialService.setName("stackoverflow");
    socialService.setOfficialLink("https://stackoverflow.com");
    accountRepository.save(account1);
    accountRepository.save(account2);
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "social_service")
private SocialService socialService;

@OneToMany(mappedBy = "socialService")
private List<Account> accounts;