2017-01-18 1 views
2

私のアプリケーションをhibernateが配備しているときにいくつか問題があります。HibernateとJPAを使用して外部キーマッピングのフィールドの順序を定義する方法は?

は、私はこのように、外部キー違反を発見したので、Hibernateがテーブルを更新することはできませんと言うログにいくつかのエラーを参照してください。

Caused by: org.postgresql.util.PSQLException: ERROR: insert or update on table "order" violates foreign key constraint "fk1w50d63tw42cwgrb7pjn11crs" 
    Detail: Key (id_office_o, id_period)=(2, 1) is not present in table "office". 

しかし、私のテーブル定義に私は(id_period, id_office_o)関係としてFK fk_order_office_o持っています。

ここに私のテーブル定義があります。

CREATE TABLE period (
    id_period INTEGER PRIMARY KEY NOT NULL, 
    initial_date TIMESTAMP, 
    final_date TIMESTAMP 
); 

CREATE TABLE office (
    id_period INTEGER NOT NULL, 
    id_office INTEGER NOT NULL, 
    large_name VARCHAR(50) NOT NULL, 
    code_name VARCHAR(2) NOT NULL, 
    CONSTRAINT pk_office PRIMARY KEY (id_periodo, id_office), 
    CONSTRAINT fk_office_period FOREIGN KEY (id_period) REFERENCES period (id_period) 
); 
CREATE UNIQUE INDEX uk_office_id_office ON office (id_office); 

CREATE TABLE order (
    id_order INTEGER PRIMARY KEY NOT NULL, 
    id_period INTEGER, 
    id_office_o INTEGER, 
    id_office_d INTEGER, 
    status INTEGER, 
    CONSTRAINT fk_order_office_o 
     FOREIGN KEY (id_period, id_office_o) 
     REFERENCES office (id_period, id_office) 
     MATCH SIMPLE ON UPDATE CASCADE ON DELETE RESTRICT, 
    CONSTRAINT fk_order_office_d 
     FOREIGN KEY (id_period, id_office_d) 
     REFERENCES office (id_period, id_office), 
     MATCH SIMPLE ON UPDATE CASCADE ON DELETE RESTRICT, 
    CONSTRAINT fk_order_period 
     FOREIGN KEY (id_period) 
     REFERENCES period (id_period) 
     MATCH SIMPLE ON UPDATE CASCADE ON DELETE RESTRICT 
); 

これは私のテーブルのデータです。

Period. 
+------------+--------------+------------+ 
| id_period | initial_date | final_date | 
|------------|--------------|------------+ 
| 1   | 2016-01-01 | 2017-12-31 | 
+------------+--------------+------------+ 

Office. 
+------------+-----------+------------+-----------+ 
| id_period | id_office | large_name | code_name | 
|------------|-----------|------------|-----------| 
| 1   | 1   | Sales  | SL  | 
| 1   | 2   | Billing | BL  | 
| 1   | 3   | Shipments | SH  | 
| 1   | 4   | Returns | RT  | 
+------------+-----------+------------+-----------+ 

Order. 
+------------+-----------+--------------+--------------+-----------+ 
| id_order | id_period | id_office_o | id_office_d | status | 
+------------+-----------+--------------+--------------+-----------+ 
| 1   | 1   | 2   | 3   | 1   | 
| 2   | 1   | 2   | 3   | 1   | 
| 1   | 1   | 3   | 4   | 1   | 
| 1   | 1   | 1   | 2   | 1   | 
+------------+-----------+--------------+--------------+-----------+ 

あなたが見ることができるように、注文テーブルに関連officeテーブルのFKはthatsのために、id_periodid_officeを使用fk_order_office_oという名前の制約を持っています。

エンティティのマッピングはここにある:

@Embeddable 
public class OfficePK implements Serializable { 

    @Column(name = "id_period") 
    private Integer idPeriod; 

    @Column(name="id_office") 
    private Integer idOffice; 

    public OfficePK() { 
    } 

    public OfficePK(Integer idPeriod, Integer idOffice) { 
     this.idPeriod = idPeriod; 
     this.idOffice = idOffice; 
    } 

    ... 

} 


@Entity 
@Table(schema="enterprise", name="office") 
public class Office { 


    @EmbeddedId 
    private OfficePK idOffice; 

    private String largeName; 
    private String codeName; 

    public Office() { 
    } 

    public OfficePK getIdOffice() { 
     return this.idOffice; 
    } 

    public void setIdOffice(OfficePK idOffice) { 
     this.idOffice = idOffice; 
    } 

    ... 

} 


@Entity 
@Table(schema="operation", name = "order") 
public class Order { 

    @Column(name="id_order") 
    private Integer idOrder; 

    @ManyToOne 
    @JoinColumns(
     value = { 
      @JoinColumn(name="id_period", 
         referencedColumnName = "id_period", 
         nullable = false, insertable = false, 
         updatable = false), 
      @JoinColumn(name="id_office_o", 
         referencedColumnName = "id_office", 
         nullable = false, insertable = false, 
         updatable = false) 
     }, 
     foreignKey = @ForeignKey(name = "fk_order_office_o") 
    ) 
    private Office officeO; 

    @ManyToOne 
    @JoinColumns(
     value = { 
      @JoinColumn(name="id_period", 
         referencedColumnName = "id_period", 
         nullable = false, insertable = false, 
         updatable = false), 
      @JoinColumn(name="id_office_d", 
         referencedColumnName = "id_office", 
         nullable = false, insertable = false, 
         updatable = false) 
     }, 
     foreignKey = @ForeignKey(name = "fk_order_office_d") 
    ) 
    private Office officeD; 

    public Order() { 
    } 

    ... 

} 

アプリケーションが配備されたとき、私は私のatentionを呼び出すいくつかのエラーを参照してください。

  1. 私が注文のthatsの外部キーを定義しませんログファイルに表示すると、ログファイルは(id_office_o, id_period)のペアを探していますが、外部キーはテーブルとマッピングで(id_period, id_office_o)と定義されています。
  2. 私は、外部キーの名前を設定するんだけど、Hibernateはfk1w50d63tw42cwgrb7pjn11crsことが可能です?エンティティの外部キーマッピングにフィールドの順序を定義することができますどのよう

のようにランダムな名前を設定しています外部キーのフィールドを定義またはマッピングする方法は?

私は

  1. 休止5.2.6.Final
  2. 春JPA 1.10.6.RELEASE

にみんなありがとうを使用しています。

+1

'@ManyToOne @JoinColumn(名前は=「id_period」) プライベート整数idPeriod;' ManyToOneアノテーションは整数 –

+0

のために使用することはできませんそれは私が議事録に間違っていた、正しいですが、私はすでにそれを修正し、感謝@MdZahidRaza – isccarrasco

答えて

2

@ForeignKeyに関連する部分は、HHH-11180に関連している可能性があります。

外部キーの順序についての部分は、デフォルトorg.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImplから延びており、それはあなたが必要とするために、列の外部キーを生成するようにdetermineForeignKeyNameメソッドをオーバーライドするカスタムorg.hibernate.boot.model.naming.ImplicitNamingStrategy実装を提供することにより、それを解決することができます。

今、スキルを適切に管理していないという匂いがあります。本番環境で自動HBM2DDLスキーマ生成を使用しないでください。 You should use Flyway instead。それがあなたの環境の根本的な問題です。

+0

ありがとう@ vlad-mihalcea、私は 'none'の' hbm2ddl'設定で、FK名とプロダクション環境の 'ImplicitNamingStrategy'を実装しています。 – isccarrasco