1

Hibernate の EntityManager が起動し、エンティティのマッピングを検証しているときに問題が発生しています。私がドラフトできる最も簡単な言葉で言えば、次の 4 つのクラスがあります。

@Entity
@Table(name="abc_rule")
public class Rule {
  @Id
  @Column(name="id")
  private Integer id;

  @ManyToOne
  private RuleType ruleType;
}

@Entity
@Table(name="abc_rule_type")
@IdClass(RuleTypeKey.class)
public class RuleType {
  @Id
  private String typeCode;

  @Id
  private String otherCode;

  @Column(name="descr")
  private String description;
}

public class RuleTypeKey {
  @Id
  @Column(name="type_cd")
  private String typeCode;

  @Id
  @Column(name="other_cd")
  private String otherCode;
}

@Entity
@Table(name="abc_rule_type")
public class RuleTypeSimple {

  @Id
  @Column(name="id")
  private Integer id;

  @Column(name="type_cd")
  private String typeCode;

  @Column(name="other_cd")
  private String otherCode;

  @Column(name="descr")
  private String description;
}

Hibernate の起動時に、次の例外が発生します。

外部キー (FK4AD4C4B924F958E2:abc_rule [ruleType_type_cd,ruleType_other_cd])) には、参照される主キー (abc_rule_type [id]) と同じ数の列が必要です。

@Table アノテーションの名前を一時的に に変更するRuleTypeSimple"abc_rule_type_123"、Hibernate は期待どおりにマッピングを検証して使用します。私には、Hibernate が、参照されている実際のクラスのセットアップではなく、テーブル名に基づいて外部キー マッピングを検証しているように見えます。

クラスに基づいて Hibernate を強制的に検証する、私が見逃している明らかな何かがありますか? または、外部キーを検証せずに、私が正しく行ったことを信頼するようにするには?

補足として、クラスを 2 つの異なる識別子設定で 2 回マップする正当な理由がないことはわかっています。私の場合、同じデータベースで動作するコードの 2 つの異なるプロジェクトのマージが原因です。1 つは読み取り専用で使用されるため、この異常なマッピングを回避できます。残念ながら、両方のコード ベースには、クラスのバージョンにラップされた大量のコードが含まれており、リファクタリングは大がかりな作業になるでしょう。

4

1 に答える 1

1

HibernateはORMツールであるため、いくつかのOOPルールまたはベストプラクティスに従って、それを利用するようにしてください。

主キーとして複数の列を使用することはまったく行わないでください。完全に強制された場合(そうでない場合に誰かがあなたを殺そうとしている場合や、古代のリレーショナルデータベースがすでに作成されていて、人間の外部にいる場合など)制限)次に、@EmbeddedIdで注釈が付けられた@EmbedableIdを使用する必要があります。また、すべての列に@Id注釈で注釈を付けないでください。

EmbeddedIdの例を次に示します。EmbeddedCompoundPrimaryKeyの

その間、作成するモデルが何であるかはわかりませんが(少なくとも、図または表のスクリプトを投稿すると役立ちます)、この修正により、エラーが増えることはありません。

@Entity
@Table(name="abc_rule")
public class Rule {
  @Id
  @Column(name="id")
  private Integer id;

  @ManyToOne
  private RuleType ruleType;
}

@Entity
@Table(name="abc_rule_type")
//@IdClass(RuleTypeKey.class) <--I don't think this is right
public class RuleType {
  @EmbeddedId //Add this
  private RuleTypeKey id; //And this
  /* Remove this
  @Id
  private String typeCode;

  @Id
  private String otherCode;*/

  @Column(name="descr")
  private String description;
}

@Embeddable //Add this
public class RuleTypeKey {
  //@Id <--remove this
  @Column(name="type_cd")
  private String typeCode;

  //@Id <--remove this
  @Column(name="other_cd")
  private String otherCode;
}

@Entity
//@Table(name="abc_rule_type") <--must be different table name
@Table(name="abc_rule_type_simple")
public class RuleTypeSimple {

  @Id
  @Column(name="id")
  private Integer id;

  @Column(name="type_cd")  //Are this two colums a reference to 
  private String typeCode; //The RuleType too?? if so the must be
                           //The same as in class Rule (ManyToOne)

  @Column(name="other_cd")
  private String otherCode;

  @Column(name="descr")
  private String description;
}

それを試して、それが機能するかどうか私に知らせてください(それはいくつかのsintaxエラーがあるかもしれません、それをチェックしてください)

于 2012-08-08T18:56:50.607 に答える