【发布时间】:2014-11-03 14:30:01
【问题描述】:
我有一个使用 liquibase 和 postgresql 的 sprint-boot 1.1.4.RELEASE 应用程序。
我有两个实体:
@Entity
public class Menu {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long menuId;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "menu", fetch = FetchType.EAGER)
private List<MenuItem> menuItems = new ArrayList<MenuItem>();
@ManyToOne
@JoinColumn(name = "subscriptionPackageId", nullable = false)
private SubscriptionPackage subscriptionPackage;
private String displayText;
private int displayOrder;
和
@Entity
public class MenuItem {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long menuItemId;
private String displayText;
private String path;
private String toolTip;
private int displayOrder;
@ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinColumn(name = "menuId", nullable = false)
private Menu menu;
@Enumerated(EnumType.STRING)
@Column(name = "callType", nullable = false)
private HttpType callType;
我的 db.changelog-master.xml 中有以下内容:
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd"
objectQuotingStrategy="QUOTE_ALL_OBJECTS">
<changeSet id="1" author="me" >
<preConditions onFail="MARK_RAN">
<not>
<tableExists tableName="SubscriptionPackage"/>
<tableExists tableName="Menu"/>
<tableExists tableName="MenuItem"/>
</not>
</preConditions>
<createSequence sequenceName="hibernate_sequence"/>
<createTable tableName="SubscriptionPackage">
<column name="subscriptionPackageId" type="bigint" autoIncrement="true">
<constraints primaryKey="true"/>
</column>
<column name="servicePackage" type="varchar(300)"/>
<column name="description" type="varchar(500)"/>
</createTable>
<createTable tableName="Menu">
<column name="menuId" type="bigint" autoIncrement="true">
<constraints primaryKey="true"/>
</column>
<column name="subscriptionPackageId" type="bigint"/>
<column name="displayText" type="varchar(300)"/>
<column name="displayOrder" type="int"/>
</createTable>
<createTable tableName="MenuItem">
<column name="menuItemId" type="bigint" autoIncrement="true">
<constraints primaryKey="true"/>
</column>
<column name="menuId" type="bigint">
<!--<constraints foreignKeyName="fk_menu_item" references="Menu(menuId)"/>-->
</column>
<column name="displayText" type="varchar(100)"/>
<column name="path" type="varchar(100)"/>
<column name="toolTip" type="varchar(500)"/>
<column name="displayOrder" type="int"/>
<column name="callType" type="varchar(50)"/>
</createTable>
</changeSet>
</databaseChangeLog>
在启动时执行,postgresql 向我显示了表的以下 sql:
CREATE TABLE "Menu"
(
"menuId" bigserial NOT NULL,
"subscriptionPackageId" bigint,
"displayText" character varying(300),
"displayOrder" integer,
CONSTRAINT pk_menu PRIMARY KEY ("menuId")
)
CREATE TABLE "MenuItem"
(
"menuItemId" bigserial NOT NULL,
"menuId" bigint,
"displayText" character varying(100),
path character varying(100),
"toolTip" character varying(500),
"displayOrder" integer,
"callType" character varying(50),
CONSTRAINT pk_menuitem PRIMARY KEY ("menuItemId"),
CONSTRAINT fk_menu_item FOREIGN KEY ("menuId")
REFERENCES "Menu" ("menuId") MATCH SIMPLE
ON UPDATE RESTRICT ON DELETE CASCADE
)
我有一个 MenuRepository:
@Repository
public interface MenuRepository extends CrudRepository<Menu, Long> {
List<Menu> findAll();
List<Menu> findBySubscriptionPackage( SubscriptionPackage subscriptionPackage);
}
在启动时,以下行导致异常:
List<Menu> menus = menuRepository.findAll()
这是:
Caused by: org.postgresql.util.PSQLException: ERROR: relation "menu" does not exist
Position: 166
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
正在提交的sql是:
select menu0_.menu_id as menu_id1_0_, menu0_.display_order as display_2_0_, menu0_.display_text as display_3_0_, menu0_.subscription_package_id as subscrip4_0_ from menu menu0_
我认为我的映射很好,菜单包含许多双向关系的菜单项。我有一些其他映射因相同类型的问题而失败,并且关系错误名称中有下划线而不是驼峰式大小写;这让我想知道这是否是我使用 spring.jpa.hibernate.ejb.naming_strategy=org.hibernate.cfg.EJB3NamingStrategy
的副作用根据“a_horse_with_no_name”的优秀建议,我通过不带引号的 SQL 手动创建了 Menu 表,但又遇到了另一个错误:
Caused by: org.postgresql.util.PSQLException: ERROR: column menu0_.menu_id does not exist
这也是一个大小写问题,所以我必须错误地配置 Liquibase 来告诉 Postgresql 忽略大小写和驼峰式。
我在变更日志中尝试了以下内容:
objectQuotingStrategy="LEGACY"
objectQuotingStrategy="QUOTE_ALL_OBJECTS"
objectQuotingStrategy="QUOTE_ONLY_RESERVED_WORDS"
所有三个都用引号创建我的表和列。
【问题讨论】:
-
您使用带引号的标识符创建了表,这意味着它们现在区分大小写。
"Menu"是与menu不同的表名。我建议重新创建不带任何引号的所有表。从长远来看,这会给您带来更少的麻烦。 -
我看不到我在哪里创建了带引号的表格。我在 XML 中为 liquibase 定义了它们。你的意思是这是一个区分大小写的问题,我应该使用 @Table(name="menu") 或其他什么这样的情况是正确的?我不确定我是否理解你的意思。
-
CREATE TABLE "MenuItem"- 也许这是你在 Liquibase 中定义它们的方式。 -
我不知道如何告诉 Liquibase 在没有它的情况下创建数据库表。如果我理解你,我的表和实体被命名为“菜单”,而关系是“菜单”?我有另一个错误,表是 SubscriptionPackage,缺少关系是“subscription_package”,这也是区分大小写的问题吗?
-
好的,所以我通过不带引号的 SQL 手动创建了菜单表,这让我克服了那个错误,然后出现了其他错误:错误:列 menu0_.menu_id 不存在所以这看起来像引用/案例/camelCase 问题。当我使用 Liquibase 创建和管理我的数据库时,我做错了什么?我将更新我的问题以显示整个更改文件。
标签: postgresql spring-boot liquibase