2014-09-10 2 views
0

저는 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> 

시작에서 실행됩니다

나는 두 기관이 up 및 postgresql은 테이블에 대해 다음 sql을 표시합니다.

시동시

@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을

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 
) 

0 I는 MenuRepository을 제출 :

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_ 

내 매핑이 좋다고 생각합니다. Menu에는 양방향 관계로 많은 MenuItem이 포함되어 있습니다. 동일한 유형의 문제로 실패하는 다른 매핑이 있는데, 그 중 일부는 관계 오류 이름에서 낙타의 경우보다 강조됩니다. 어떤이 사용 날의 부작용인지 궁금한데 "a_horse_with_no_name"우수한 제안에 근거하여

, 나는 수동으로 메뉴 테이블을 생성 spring.jpa.hibernate.ejb.naming_strategy = org.hibernate.cfg.EJB3NamingStrategy 이것은 또한 경우 문제입니다, 그래서 잘못 케이스와 낙타 표기법을 무시 PostgreSQL을 알려 Liquibase를 구성해야

Caused by: org.postgresql.util.PSQLException: ERROR: column menu0_.menu_id does not exist 

: 따옴표없이 SQL을 통해 나는 또 다른 오류가 발생했습니다.

나는 내 변경 로그에 다음과 같은 시도 :

objectQuotingStrategy="LEGACY" 
objectQuotingStrategy="QUOTE_ALL_OBJECTS" 
objectQuotingStrategy="QUOTE_ONLY_RESERVED_WORDS" 

와 세 따옴표로 내 테이블과 열을 만듭니다.

+0

따옴표로 묶인 식별자를 사용하여 테이블을 만들었습니다. 즉, 대소 문자를 구분합니다. ''Menu "는'menu'와는 다른 테이블 이름입니다. 따옴표없이 모든 테이블을 다시 만드는 것이 좋습니다. 장기적으로 문제가 발생하지 않습니다. –

+0

따옴표가있는 테이블을 어디에 생성했는지 알지 못합니다. XML에서 liquibase를 정의했습니다. 이것은 대소 문자가 민감한 문제라는 것을 의미합니까? @Table (name = "menu") 또는 대소 문자가 올바른지 사용해야합니다. 나는 당신이 의미하는 바를 잘 모르겠다. – sonoerin

+0

'CREATE TABLE "MenuItem"'- 아마 당신이 Liquibase에서 정의한 방식 일 것입니다. –

답변

0

좋아요, 문제가 해결되어 다른 사람이 같은 문제를 겪고있는 경우 게시 할 예정입니다. 스프링 부트 (Spring-Boot) 등은 열 이름에 camelCase 대신 밑줄이 올 것으로 예상됩니다. 에 "_"사이의 엔티티 경우가

@Entity 
@Table(name = "MENU") 
public class Menu { 
... 
} 

: 다음 또한 각 개체에 테이블 이름을 선언해야

<createTable tableName="MENU"> 
      <column name="menu_id" type="bigint" autoIncrement="true"> 
       <constraints primaryKey="true"/> 
      </column> 
      <column name="subscription_package_id" type="bigint"/> 
      <column name="display_text" type="varchar(300)"/> 
      <column name="display_order" type="int"/> 
     </createTable> 

: 나는로 내 liquibase의 변경 집합을 변경했습니다. EJBNamingStrategy를 사용하는 것처럼 이것을 재정의 할 방법이 있는지, 아니면해야하는지 여부는 알 수 없습니다. 어디서나 문서화 된 것을 발견 할 수 없었지만 스프링 우드 플라이 웨이 프로젝트의 통합 테스트에서이 사실을 알게되었습니다.

이것은 틀린 느낌입니다. 이전 엔티티에서 테이블 이름을 선언 할 필요가 없지만 Postgresql을 처음 사용하므로 대소 문자를 구분하거나 문제가있는 경우 말할 수 없습니다. 이 말이 맞다면 다시 듣고 싶습니다. 어딘가에서 실수를 저 지르지 않았 으면합니다.

관련 문제