【问题标题】:Spring Boot reference on old entity version旧实体版本上的 Spring Boot 参考
【发布时间】:2019-08-13 08:53:21
【问题描述】:

我在使用 Spring Boot 时遇到问题。我在资源文件夹中有一个 Schema.sql 和一个实体。在第一个应用程序运行时,一切都按预期工作。但是当我更改 schema.sql 中的列名、更新我的实体、删除数据库表并重新运行应用程序时,Spring 总是创建旧的实体列名。

在我的 application.properties 我有以下条目:

spring.datasource.name                   = mydatasource
spring.datasource.url               = jdbc:mysql://localhost:3306/dbname?serverTimezone=UTC&createDatabaseIfNotExist=true
spring.datasource.driver-class-name      = com.mysql.cj.jdbc.Driver
spring.datasource.password               = password
spring.datasource.username               = username

spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=update

security.oauth2.client.clientId= my_client
security.oauth2.resource.id= myid
security.oauth2.client.clientSecret= my_srcret
security.oauth2.client.accessTokenUri= http://localhost:8080/api/oauth/token
security.oauth2.client.userAuthorizationUri= http://localhost:8080/api/oauth/authorize
security.oauth2.resource.token-info-uri=http://localhost:8080/api/oauth/check_token

logging.level.org.springframework.web=DEBUG

我的新实体:

@Entity
@Table(name = "organizers")
public class Organizer implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;
    @Column(name = "commercialName")
    private String commercialName;
    @Column(name = "org_description")
    private String description;
    @Column(name = "verified")
    private boolean verified;
    @Column(name = "isOnline")
    private boolean isOnline;
    @Column(name = "org_type")
    private OrganizerType type;
    @Column(name = "alias")
    private String alias;
    @Column(name = "fone")
    private String fone;
    @OneToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "userId")
    private User user;
}

我的新 Schema.sql

create table if not exists organizers
(
    id             bigint PRIMARY KEY NOT NULL AUTO_INCREMENT,
    userId         varchar(256)             not null,
    commercialName varchar(100)       not null,
    description    varchar(1000)      not null,
    verified       boolean default 0,
    isOnline       boolean default 0,
    type           int                not null,
    alias          varchar(100)       not null,
    fone        varchar(100)       not null,
    constraint fk_user_id FOREIGN KEY (userId) REFERENCES users (username)
);

这是 Spring 创建的屏幕截图:

正如您在图片中看到的,Spring 总是根据我的旧模式和实体创建组织者表!我正在使用 Spring Boot 2.1.6 版和 MySql 8.0.17 版

我认为 Spring Boot 总是缓存我的旧 Schema.sql 或我的旧实体!可能是什么问题?

【问题讨论】:

  • 希望你的项目中只有一个 Schema.sql。
  • 是的,我只有一个
  • org_type 专栏的问题吗?
  • 一般来说没有。我通过设置 jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl 解决了这个问题并删除了 dll-auto

标签: java mysql spring hibernate spring-boot


【解决方案1】:

它没有引用旧的实体版本,它只是看起来像那样。在应用程序属性中设置 spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy。

默认情况下,spring 使用 org.springframework.boot.orm.jpa.SpringNamingStrategy。这会将诸如商业名称(在骆驼情况下)之类的任何内容转换为商业名称。设置上述属性将覆盖此行为。

【讨论】:

  • 我设置了 spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.EJB3NamingStrategy 但没有帮助。此属性已弃用
  • 对不起,我忘记了它已被弃用。你可以试试 baeldung.com/hibernate-naming-strategy 的 ImplicitNamingStrategyJpaCompliantImpl
  • 现在我在尝试保存实体时遇到了另一个问题:java.sql.SQLSyntaxErrorException:'字段列表'中的未知列'commercial_name'。 Table 和 Entity 中的列名是驼峰式的。但是我不知道春天是从哪里弄来这个蛇壳的
  • 我通过将策略更改为 spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl 解决了这个问题,谢谢
【解决方案2】:
spring.jpa.hibernate.ddl-auto=update

设置为update,所以休眠更新你的架构,它应该被完全删除,这样flyway可以从schema.sql创建架构。

此外,您需要添加以下配置以启用从 flyway 创建架构:

spring.datasource.initialization-mode=always

来自文档Database Initialization

在基于 JPA 的应用程序中,您可以选择让 Hibernate 创建模式或使用 schema.sql,但不能同时使用这两种方法。如果您使用 schema.sql,请确保禁用 spring.jpa.hibernate.ddl-auto。

此外,您的实体映射存在错误。新实体引用列 @Column(name = "org_description"),但在您的新架构定义中,该列仅称为 description,一旦架构创建工作,您需要更新列映射。

【讨论】:

  • 感谢您对我的错误的提示。我从 application.properties 中删除了 spring.jpa.hibernate.ddl-auto=update 并更新了列名。但现在 spring 不创建表
  • 尝试设置属性 spring.datasource.initialization-mode=always 并通读整个文档。
  • 谢谢我设置 spring.datasource.initialization-mode=always 和 spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl 及其现在工作
  • 当您在每个字段上使用@Column 注释时,您不需要覆盖命名策略。它应该在不设置命名策略的情况下工作。我将 spring.datasource.initialization-mode=always 添加到我的答案中。随意接受对您最有帮助的答案。
猜你喜欢
  • 1970-01-01
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
  • 1970-01-01
  • 1970-01-01
  • 2019-10-08
相关资源
最近更新 更多