0

4 つの列を持つテーブル「グループ」があります。データベースは postgres で、group_id 列は Serial です。したがって、実際には、次の値を取得するためのデフォルトを持つ整数です。

@SQLInsert を使用する必要があるユースケースがあります (通常の永続化メソッドの使用はオプションではありません) が、デフォルトでは機能しません。ここに私が持っているものがあります:

@SQLInsert(sql="INSERT INTO groups (group_id, parent_id, group_name, version) VALUES (DEFAULT,?,?,?)")

エンティティ属性を group_id と version が null の値に設定し、他の 2 つは正しく設定されています。group_id は DB でヌル可能ではありません。バージョンはヌルにすることができます。

私はこの例外を受け取ります:

WARNING: SQL Error: 0, SQLState: 22023
SEVERE: The column index is out of range: 4, number of columns: 3.
SEVERE: Could not synchronize database state with session

次の DML をデータベースに直接入力すると、機能します。

INSERT INTO groups (group_id, parent_id, group_name, version) VALUES (DEFAULT, 3, 'abcd', null); 

@SQLInsert を使用して同じことを実現する方法はありますか。

4

2 に答える 2

0

したがって、短い答えは「この方法では実行できません」です。これが尋ねられたのを見たかなりの数の場所にもかかわらず、Hibernate の人々はこのユースケースを提供していません。

私の解決策は、Postgres シーケンスをテーブルから切り離すことでした。つまり、シーケンスから nextval を選択し、2 つの主キー フィールドの 1 つを入力するデフォルトの制約を削除しました。

次に、ネイティブ クエリを使用して手動で nextval を取得し (データベースを非抽象化する必要があります)、その値を使用して主キー フィールドを手動で入力します。できます。汚いですが、もっと頻繁に使うかもしれません。確かに、純粋な ORM メソッドを使用するよりも、何が起こっているかについてはるかに理解しやすいものです。これは魔法使いの帽子がなくてもデバッグできます。:)

public class...
@PersistenceContext(unitName = "persistence_unit")
private EntityManager em;

...
mymethod(){
...
Query q = em.createNativeQuery("SELECT nextval('groups_group_id_seq')");
BigInteger groupId = (BigInteger)q.getSingleResult();

BigInteger parentId = methodToGetParentId();

GroupsPK gpk = new GroupsPK(groupId, parentId);

Groups grps = new Groups(gpk, "other parameters");

...
}
于 2012-06-05T19:33:05.973 に答える
0

保存するクラス メンバーが参照型でない場合、null 値を保持することはできません。データベースのレコードとの同期に失敗する原因となっている可能性があります。Integer や Double などの参照型を使用してみてください。また、直接挿入クエリでデフォルト値が想定されることを確認してください。

エラーメッセージの別のこと。デフォルト値は、Java でその列に使用している型の境界を超えている可能性があります。デフォルト値が範囲内であることを確認してください。クラス メンバーに範囲外の値が設定されている場合、同期できません。

編集: 申し訳ありませんが、この場合、2 番目の部分は当てはまりません。

于 2012-06-05T11:33:04.173 に答える