JPAがキータイプに関係なくJoincolumnの文字列を選択するのはなぜですか?
-
25-09-2019 - |
質問
Eclipselink JPA2実装を使用します(Hibernateの実装と同じかどうかはわかりません)
組織エンティティに契約がある単純な構造があります。これがPostgresからエクスポートして組織を作成したSQLです
CREATE TABLE organization (
key bigint NOT NULL,
version integer
);
このような組織の契約側を指定した場合:
@ManyToOne( optional=false )
@JoinColumn( name="organization_key", referencedColumnName="key" )
private Organization organization;
そして、スキーマを捨ててください私はこれを手に入れます。
CREATE TABLE contract (
key bigint NOT NULL,
version integer,
organization_key character varying(255),
);
組織キーを参照するために、さまざまな(255)フィールド(255)フィールドを使用することは意味がありません。次のように列definitionを使用できることは知っています。
@ManyToOne( optional=false )
@JoinColumn( name="organization_key", referencedColumnName="key", columnDefinition="bigint NOT NULL" )
private Organization organization;
文字タイプの代わりにBigIntタイプを取得します。
正しい列タイプを取得することを期待することは私にとって非現実的ですか?私はそれを間違って使用していますか、それとも間違った期待がありますか?毎回columnDefinitionを使用する必要があることが期待されていますか?
アップデート:組織エンティティからの関連情報は次のとおりです
@Entity
@Table( name = "organization" )
@SequenceGenerator( name = "ORGANIZATION_SEQ_GEN", sequenceName = "ORGANIZATION_SEQUENCE" )
public class Organization
implements DataObject<Long>
{
/**
* key for this instance. Should be managed by JPA provider.
*/
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "ORGANIZATION_SEQ_GEN" )
private Long key;
/**
* JPA version column
*/
@Version
protected int version;
/**
* All contracts for this organization
*/
@OneToMany(mappedBy="organization" )
@OrderBy( "endDate DESC" )
private List<Contract> contracts;
... getters and setters
}
そして、これが契約エンティティです
@Entity
@Table( name = "contract" )
@SequenceGenerator( name = "CONTRACT_SEQ_GEN", sequenceName = "CONTRACT_SEQUENCE" )
public class Contract
implements DataObject<Long>
{
/**
* key for this instance. Should be managed by JPA provider.
*/
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "CONTRACT_SEQ_GEN" )
private Long key;
/**
* Organization that owns this contract, required.
*/
@ManyToOne( optional=false )
@JoinColumn( name="organization_key", referencedColumnName="key" )
private Organization organization;
/**
* JPA version column
*/
@Version
protected int version;
... getters and setters
}
解決
正しい列タイプを取得することを期待することは私にとって非現実的ですか?
いいえ、それは非現実的ではなく、現在の結果は明らかに予想外です。
私はそれを間違って使用していますか、それとも間違った期待がありますか?
あなたのマッピングは間違っているようには見えません。次のことを試して、同じ結果が得られることを確認できますか(私は単に省略しています referencedColumnName
とにかく定義する必要はないということです)?
@Entity
@Table( name = "contract" )
@SequenceGenerator( name = "CONTRACT_SEQ_GEN", sequenceName = "CONTRACT_SEQUENCE" )
public class Contract implements DataObject<Long> {
@Id
@GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "CONTRACT_SEQ_GEN" )
private Long key;
...
@ManyToOne( optional=false )
@JoinColumn( name="organization_key" )
private Organization organization;
...
}
私はpostgreSQLをインストールしていません、自分自身を試すことはできません。
毎回columnDefinitionを使用する必要があることが期待されていますか?
いいえ。
他のヒント
この問題は症例の感受性の1つだと思います。
キーID属性に@Columnを設定しなかったため、デフォルトの列名は「キー」です。 @ManyToOneでは、同じ列ではない「キー」を参照したため、EclipsElink(ケースに敏感で、非ID外部キー参照をサポートしています)は、これが別の列であり、知らなかった列であると仮定したので、 Varcharのデフォルトタイプです。
参照ColumnNameを「キー」に変更するか、Singleton IDを参照するときは必要ないため削除します。
列の参照が見つからない場合、または間違ったケースがある場合、またはケースを自動的に切り替えることさえあるかもしれません)に警告を記録する必要があることを、Eclipselinkにバグを記録することは価値があります。実際、私たちはすでに警告を記録しているかもしれませんが、あなたはあなたのログをチェックすることを望むかもしれません。