H2不在我的Spring Boot应用程序中创建/更新表。我的实体出了什么问题? [英] H2 not creating/updating table in my Spring Boot app. Something's wrong with my Entity?

查看:153
本文介绍了H2不在我的Spring Boot应用程序中创建/更新表。我的实体出了什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to keep some data in H2 database by making a CRUD repository, using Hibernate.

我无法让数据库存储我的条目。目前,我正在尝试通过制作样本条目来更新数据库期间实现这一点。条目在日志中看起来很好,但是没有创建/更新/生成表。

I can't get the database to store my entries whatsoever. Currently, I'm trying to achieve that during updating the db by making a sample entry. Entry is looking good in the logs, but table is not created/updated/generated.

为什么Hibernate在这种情况下无法创建表? / strong>(如果问题在于我的数据结构)

Why Hibernate is not unable to create a table in this case? (if the problem lies in structure of my data)

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

Here's my Entity, Game.java class (I've tried without @Column annotations, no difference. Id is not auto-generated, I need to be able to enter my own ID everytime):

@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;
    }


}

这里是 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数据库, application.properties 文件:

I configured H2 database here, in application.properties file:

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下测试我的存储库,其中有一个示例应将条目插入表中:

I test my repository by going under localhost:8080/test, where a sample entry should be inserted into table:

@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控制台 SELECT * FROM GAME 返回我:
SELECT * FROM GAME;
未找到GAME表; SQL语句:
SELECT * FROM GAME [42102-193] 42S02 / 42102(帮助)

It looks like data is binded to parameters, but in H2 console SELECT * FROM GAME returns me: SELECT * FROM GAME; Table "GAME" not found; SQL statement: SELECT * FROM GAME [42102-193] 42S02/42102 (Help)

我尝试过其他H2模式,如create-drop或创造,但没有成功。令我担心的是,我甚至无法让数据库创建一个具有正确行的空表,准备好输入。

I've tried other H2 modes such as create-drop or create, but no success. What worries me is that, I can't even get the database to create an empty table with the correct rows, ready for entries.

我认为这个问题或者是错误的我的实体或我的GameRepository配置中缺少,但我没有更多想法来修复此错误。

I think that something's wrong either with my Entity or missing from my GameRepository configuration, but I have no more ideas to fix this error.

我想实现这里的目的:
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/

I want to achieve what's here: http://javasampleapproach.com/spring-framework/spring-boot/integrate-h2-database-springboot-spring-jpa-embedded-mode And here: 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 /

Also, I've tried this set of tutorials for a change: 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/

但到目前为止还没有运气。

But no luck so far.

推荐答案


看起来数据绑定到参数,但在H2控制台中SELECT *
FROM GAME不返回任何内容。该表不存在。

It looks like data is binded to parameters, but in H2 console SELECT * FROM GAME returns me nothing. The table doesn't exist.

您在内存中使用 H2的实例:

You are using an in-memory instance of H2 :

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

在此模式下,您无法从另一个客户端看到启动<$ c $的更改内容c>内存数据库。

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

In this mode, you cannot see the content of the changes from another client that which one that started the in-memory database.
To see the changes from other clients, you have to use the TCP mode.

你有两个解决方案:


  • 使用一个文件来保存H2的实例。


存储的数据库文件在哪里?

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

When using database URLs like jdbc:h2:~/test, the database is stored in the user directory. For Windows, this is usually C:\Documents and Settings\ or C:\Users\. If the base directory is not set (as in jdbc:h2:./test), the database files are stored in the directory where the application is started (the current working directory). When using the H2 Console application from the start menu, this is /bin. The base directory can be set in the database URL. A fixed or relative path can be used. When using the URL jdbc:h2:file:./data/sample, the database is stored in the directory data (relative to the current working directory). The directory is created automatically if it does not yet exist. It is also possible to use the fully qualified directory name (and for Windows, drive name). Example: jdbc:h2:file:C:/data/test




  • 保持使用in-内存实例,但使用TCP模式。

  • 替换:

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

    by:

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

    一般情况下,我在JPA实体单元测试期间切换到此模式,当我真的想知道插入哪个时数据库。

    Generally, I switch to this mode during JPA entity unit testing when I really want to know which was inserted in the database.

    来自官方文档


    内存数据库

    对于某些用例(例如:快速原型设计,测试,高
    性能操作,只读数据库),可能不需要
    来保存数据,或者持续更改为数据。此数据库
    支持内存模式,其中数据不会保留。
    ...

    For certain use cases (for example: rapid prototyping, testing, high performance operations, read-only databases), it may not be required to persist data, or persist changes to the data. This database supports the in-memory mode, where the data is not persisted. ...

    在某些情况下,只有一个与内存数据库的连接需要
    。这意味着要打开的数据库是私有的。在这个
    的情况下,数据库URL是jdbc:h2:mem:在
    内打开两个连接,同一个虚拟机意味着打开两个不同的(私有)
    数据库。

    In some cases, only one connection to a in-memory database is required. This means the database to be opened is private. In this case, the database URL is jdbc:h2:mem: Opening two connections within the same virtual machine means opening two different (private) databases.

    有时,与同一内存数据库的多个连接需要
    。在这种情况下,数据库URL必须包含名称。示例:
    jdbc:h2:mem:db1。使用此URL访问同一数据库仅在同一虚拟机和类加载器环境中使用

    Sometimes multiple connections to the same in-memory database are required. In this case, the database URL must include a name. Example: jdbc:h2:mem:db1. Accessing the same database using this URL only works within the same virtual machine and class loader environment.

    从另一个访问内存数据库进程或从另一台
    计算机,您需要在创建
    内存数据库的同一进程中启动TCP服务器。然后其他进程需要
    通过TCP / IP或TLS访问数据库,使用数据库URL,例如:
    jdbc:h2:tcp:// localhost / mem:db1。






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

    确实,H2数据库提供了一个基于浏览器的控制台 Spring Boot可以为你自动配置
    。当满足这些
    条件时,控制台会自动配置:

    Indeed the H2 database provides a browser-based console that Spring Boot can auto-configure for you. The console is auto-configured when these conditions are met :



    • 您正在开发一个servlet基于Web应用程序。

    • com.h2数据库:h2在类路径上。

    • 您正在使用Spring Boot的开发人员工具。

    所以这意味着只能在dev中访问。一般你想要什么。

    So it means that will be accessible only in dev. What generally you want.

    默认情况下,控制台位于 / h2-console

    设置 spring.h2.console.path 要更改的属性。

    By default, the console is available at /h2-console.
    Set the spring.h2.console.path property to change that.

    这篇关于H2不在我的Spring Boot应用程序中创建/更新表。我的实体出了什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆