代码之家  ›  专栏  ›  技术社区  ›  VapeKop

H2未在我的Spring Boot应用程序中创建/更新表。我的实体有问题吗?

  •  18
  • VapeKop  · 技术社区  · 8 年前

    我想通过使用Hibernate创建CRUD存储库,在H2数据库中保留一些数据。

    在这种情况下,为什么Hibernate不能创建表? (如果问题在于我的数据结构)

    这是我的实体, Game.java 类(我尝试过没有@Column注释,没有区别。Id不是自动生成的,我需要能够每次输入自己的Id):

    @Entity
    @Table(name = "GAME")
    public class Game {
    
        @Id
        @Column (name = "ID")
        private long id;
    
        @Column (name = "NAME")
        private String name;
    
        @Column(name = "STORYLINE", length = 4000)
        private String storyline;
    
        @Column(name = "AGGREGATED_RATING")
        @JsonProperty("aggregated_rating")
        private double aggregatedRating;
    
        @Column(name = "FIRST_RELEASE_DATE")
        @JsonProperty("first_release_date")
        private long firstReleaseDate;
    
        @Embedded
        private Cover cover;
    
        public Game(){
    
        }
    
        public Game(long id, String name, String storyline, double aggregatedRating, long firstReleaseDate, Cover cover) {
            this.id = id;
            this.name = name;
            this.storyline = storyline;
            this.aggregatedRating = aggregatedRating;
            this.firstReleaseDate = firstReleaseDate;
            this.cover = cover;
        }
    
        public long getId() {
            return id;
        }
    
        public String getName() {
            return name;
        }
    
        public String getStoryline() {
            return storyline;
        }
    
        public double getAggregatedRating() {
            return aggregatedRating;
        }
    
        public long getFirstReleaseDate() {
            return firstReleaseDate;
        }
    
        public Cover getCover() {
            return cover;
        }
    
    
    }
    

    这是 封面.java 类别:

    @Embeddable
    public class Cover {
    
        @Column (name = "URL")
        private String url;
        @JsonProperty("cloudinary_id")
        @Column (name = "CLOUDINARY_ID")
        private String cloudinaryId;
        @Column (name = "WIDTH")
        private Integer width;
        @Column (name = "HEIGHT")
        private Integer height;
    
        public Cover(){
        }
    
        public Cover(String url, String cloudinaryId, Integer width, Integer height) {
            this.url = url;
            this.cloudinaryId = cloudinaryId;
            this.width = width;
            this.height = height;
    }
    
        public String getUrl() {
            return url;
        }
    
        public String getCloudinaryId() {
            return cloudinaryId;
        }
    
        public Integer getWidth() {
            return width;
        }
    
        public Integer getHeight() {
            return height;
        }
    
    }
    

    我在这里配置了H2数据库,在 文件:

    spring.h2.console.enabled=true
    spring.h2.console.path=/h2_console
    spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
    spring.datasource.username=sa
    spring.datasource.password=
    spring.datasource.driverClassName=org.h2.Driver
    spring.jpa.hibernate.ddl-auto = update
    spring.jpa.show-sql=true
    logging.level.org.hibernate.SQL=DEBUG
    logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
    

    存储库 配置如下:

    import org.springframework.data.repository.CrudRepository;
    
    import java.util.List;
    
    public interface GameRepository extends CrudRepository<Game, Long> {
        List<Game> findAllByName(String name);
    }
    

    我通过在localhost:8080/test下测试我的存储库,其中一个示例条目应该插入到表中:

    @RequestMapping("/test")
    public String saveSth(){
        gameRepository.save(new Game(127, "Assassin's Creed II", "The lineage continues as this new chapter introduces Ezio, inheritor of the talents and creed of the Assassins. His family murdered by rival families, Ezio resolves to learn the ancient art of the Assassin in order to seek revenge. He will not do so alone though, allying with historical figures such as philosopher and writer Niccolò Machiavelli. You will also be able to master the art of the assassin with all new weapons and instruments created by the renowned inventor and genius of the Renaissance, Leonardo Da Vinci himself.", 90.25, 1258416000000L, new Cover("//images.igdb.com/igdb/image/upload/t_thumb/doczeiofd1ckpapdhqs7.jpg", "doczeiofd1ckpapdhqs7", 1000, 1426)));
        return "success";
    }
    

    我得到以下日志:

    2017-07-25 13:09:58.873 DEBUG 9442 --- [nio-8080-exec-1] org.hibernate.SQL                        : select game0_.id as id1_0_0_, game0_.aggregated_rating as aggregat2_0_0_, game0_.cloudinary_id as cloudina3_0_0_, game0_.height as height4_0_0_, game0_.url as url5_0_0_, game0_.width as width6_0_0_, game0_.first_release_date as first_re7_0_0_, game0_.name as name8_0_0_, game0_.storyline as storylin9_0_0_ from game game0_ where game0_.id=?
    Hibernate: select game0_.id as id1_0_0_, game0_.aggregated_rating as aggregat2_0_0_, game0_.cloudinary_id as cloudina3_0_0_, game0_.height as height4_0_0_, game0_.url as url5_0_0_, game0_.width as width6_0_0_, game0_.first_release_date as first_re7_0_0_, game0_.name as name8_0_0_, game0_.storyline as storylin9_0_0_ from game game0_ where game0_.id=?
    2017-07-25 13:09:58.875 TRACE 9442 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [127]
    2017-07-25 13:09:58.894 DEBUG 9442 --- [nio-8080-exec-1] org.hibernate.SQL                        : insert into game (aggregated_rating, cloudinary_id, height, url, width, first_release_date, name, storyline, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
    Hibernate: insert into game (aggregated_rating, cloudinary_id, height, url, width, first_release_date, name, storyline, id) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
    2017-07-25 13:09:58.895 TRACE 9442 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [DOUBLE] - [90.25]
    2017-07-25 13:09:58.896 TRACE 9442 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [2] as [VARCHAR] - [doczeiofd1ckpapdhqs7]
    2017-07-25 13:09:58.896 TRACE 9442 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [3] as [INTEGER] - [1426]
    2017-07-25 13:09:58.897 TRACE 9442 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [4] as [VARCHAR] - [//images.igdb.com/igdb/image/upload/t_thumb/doczeiofd1ckpapdhqs7.jpg]
    2017-07-25 13:09:58.897 TRACE 9442 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [5] as [INTEGER] - [1000]
    2017-07-25 13:09:58.897 TRACE 9442 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [6] as [BIGINT] - [1258416000000]
    2017-07-25 13:09:58.897 TRACE 9442 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [7] as [VARCHAR] - [Assassin's Creed II]
    2017-07-25 13:09:58.897 TRACE 9442 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [8] as [VARCHAR] - [The lineage continues as this new chapter introduces Ezio, inheritor of the talents and creed of the Assassins. His family murdered by rival families, Ezio resolves to learn the ancient art of the Assassin in order to seek revenge. He will not do so alone though, allying with historical figures such as philosopher and writer Niccolò Machiavelli. You will also be able to master the art of the assassin with all new weapons and instruments created by the renowned inventor and genius of the Renaissance, Leonardo Da Vinci himself.]
    2017-07-25 13:09:58.897 TRACE 9442 --- [nio-8080-exec-1] o.h.type.descriptor.sql.BasicBinder      : binding parameter [9] as [BIGINT] - [127]
    

    看起来数据绑定到参数,但在H2控制台中 返回我: 未找到表“GAME”;SQL语句: 从游戏[42102-193]42S02/42102中选择*(帮助)

    我认为我的实体或GameRepository配置中缺少了一些错误,但我没有更多的想法来修复这个错误。

    我想实现以下目标: http://javasampleapproach.com/spring-framework/spring-boot/integrate-h2-database-springboot-spring-jpa-embedded-mode http://www.simplecodestuffs.com/value-object-entity-object-in-hibernate-mapping/

    此外,我还尝试了这套教程来进行更改: https://springframework.guru/using-the-h2-database-console-in-spring-boot-with-spring-security/ https://springframework.guru/spring-boot-web-application-part-3-spring-data-jpa/

    但到目前为止运气不好。

    9 回复  |  直到 8 年前
        1
  •  29
  •   Dev M    7 年前

    只需转到H2控制台,例如: http://localhost:9090/h2-console/ 在JDBC URL字段中,键入 jdbc:h2:mem:testdb

        2
  •  19
  •   davidxxx    6 年前

    看起来数据绑定到参数,但在H2控制台中选择*

    您正在使用 in-memory H2实例:

    spring.datasource.url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1
    

    内存中
    要查看其他客户端的更改,必须使用TCP模式。

    • 使用文件持久化H2实例。

    数据库文件存储在哪里?

    当使用诸如jdbc:h2:~/test之类的数据库URL时,数据库被存储 在用户目录中。对于Windows,这通常是C:\Documents和 未设置(如jdbc:h2:./test中),数据库文件存储在 启动应用程序的目录(当前工作目录 目录)。从「开始」菜单使用H2控制台应用程序时, 这是/bin。基本目录可以在中设置 数据库URL。可以使用固定或相对路径。当使用 URL jdbc:h2:文件:/数据/样本,数据库存储在 目录数据(相对于当前工作目录)。这个 如果目录尚不存在,则会自动创建该目录。它是 Windows,驱动器名)。示例:jdbc:h2:file:C:/data/test

    • 继续使用内存实例,但使用TCP模式。

    替换:

    签署人:

    spring.datasource.url=jdbc:h2:tcp://localhost/~/test
    


    从…起 the official documentation

    对于某些用例(例如:快速原型、测试、高 性能操作,只读数据库),可能不需要 支持内存模式,其中数据不会持久化。 ...

    在某些情况下,只有一个到内存中数据库的连接是 在这种情况下,数据库URL是jdbc:h2:mem:在 数据库。

    有时,同一内存数据库的多个连接是 必修的。在这种情况下,数据库URL必须包含名称。例子:

    从另一个进程或另一个进程访问内存中的数据库 内存数据库已创建。其他流程则需要 通过TCP/IP或TLS访问数据库,使用数据库URL,例如: jdbc:h2:tcp://localhost/mem:db1.


    独立H2控制台的替代方案:使用可从Spring Boot应用程序访问的H2控制台

    Spring Boot can auto-configure for you 。控制台在以下情况下自动配置: 满足以下条件:

    • 您正在开发一个基于servlet的web应用程序。
    • 通用域名格式。h2数据库:h2在类路径上。

    所以这意味着只有在dev中才可以访问。通常您需要什么。

    默认情况下,控制台位于 /h2-console
    设置 spring.h2.console.path

        3
  •  10
  •   J_mie6    5 年前

    把这一行: spring.jpa.hibernate.ddl-auto = update

        4
  •  6
  •   Ashlin Karkada    7 年前

    检查主类(Spring boot应用程序类)是否能够扫描定义的实体。当实体位于与主类不同的包中时,通常会发生这种情况。

        5
  •  2
  •   f.khantsis    5 年前

    使用 @EntityScan("com.db.jpasample.entity")

    @SpringBootApplication
    @EntityScan("com.db.jpasample.entity")
    public class GsoftApplication {
    
      public static void main(String[] args) {
        SpringApplication.run(GsoftApplication.class, args);
      }
    
    }
    

    应用程序.属性

    server.port = 9090
    spring.h2.console.enabled=true
    spring.datasource.platform=h2
    spring.datasource.url=jdbc:h2:mem:socialdb;DB_CLOSE_DELAY=-1
    spring.datasource.driverClassName=org.h2.Driver
    spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
    spring.jpa.hibernate.ddl-auto = create
    
        6
  •  1
  •   Ole Pannier Anurag    4 年前

    application.properties spring.jpa.defer-datasource-initialization=true .

        7
  •  1
  •   abhinav kumar    3 年前

    我也遇到了同样的问题,我添加了以下更改来解决它,

    我在下面的版本中添加了H2依赖项

        <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.193</version>
        </dependency>
    

    并在以下配置中添加 应用程序.属性

    spring.h2.console.enabled=true
    spring.datasource.platform=h2
    spring.datasource.driverClassName = org.h2.Driver
    spring.datasource.url=jdbc:h2:file:~/test;
    spring.datasource.username=sa
    spring.datasource.password=
    
        8
  •  0
  •   Nitin Kumar    3 年前

    SQL脚本的数据源初始化功能已在中重新设计 Spring Boot 2.5 .


    data.sql 脚本现在在初始化Hibernate之前运行。这使基于基本脚本的初始化行为与Flyway和Liquibase的行为保持一致。如果你想使用 真的 。虽然不建议混合使用数据库初始化技术,但这也将允许您使用 schema.sql 脚本以在通过填充之前在Hibernate创建的模式上构建 data.sql .

    Spring Boot 2.5 Release Notes

        9
  •  0
  •   Aayush Bhattacharya    3 年前

    我也面临同样的问题,但似乎我没有添加ddl部分

    spring.h2.console.enabled=true
    spring.datasource.url=jdbc:h2:~/test
    spring.datasource.driverClassName=org.h2.Driver
    spring.datasource.username=sa
    spring.datasource.password=   //empty as i didnt has password in h2
    spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
    spring.jpa.hibernate.ddl-auto = create //add this to create table first time then use 'update'