質問

Oracleのを使用するために休止状態になる方法を探しています SYS_GUID() 新しい行を挿入するときの関数。現在、私の DB テーブルには SYS_GUID() デフォルトとして設定されているため、Hibernate が単に値を省略した SQL を生成した場合は機能するはずです。

すべて動作していますが、現在 system-uuid ジェネレーターを使用してコードで UUID/GUID を生成しています。

@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "PRODUCT_ID", unique = true, nullable = false)
public String getId() {
    return this.productId;
}

これは問題ありませんが、GUID がデータベースによって生成された方が連続的​​であり、パフォーマンスが向上する可能性があります。さらに、これを構成する方法を知りたいだけです。

設定にはアノテーションを使用していますが、XML 設定例も素晴らしいです。

以下にテーブル定義のサンプルを示します (重要な場合に備えて)。

CREATE TABLE SCHEMA_NAME.PRODUCT
(
    PRODUCT_ID RAW(16) DEFAULT SYS_GUID() NOT NULL,
    PRODUCT_CODE VARCHAR2(10 CHAR) NOT NULL,
    PRODUCT_NAME VARCHAR2(30 CHAR) NOT NULL,
    PRODUCT_DESC VARCHAR2(512 CHAR)
)

アップデート:

「guid」を使用する Mat の解決策は機能しました。生成された SQL は次のとおりです。

Hibernate: 
    select rawtohex(sys_guid()) 
    from dual
Hibernate: 
    insert into PRODUCT
    (PRODUCT_CODE, PRODUCT_DESC, LOB_ID, PRODUCT_NAME, PROVIDER_ID, PRODUCT_ID) 
    values (?, ?, ?, ?, ?, ?)

挿入で列のデフォルト値を使用することはできないようです。そのため、アプリケーションで生成された GUID とデータベースのラウンドトリップの間で選択することになります。

役に立ちましたか?

解決

「guid」ジェネレーターを使用できる場合があります。見る この郵便受け Hibernate フォーラムから。を使用してOracleのサポートを追加したようです SYS_GUID() 少し前ですが、 ドキュメンテーション 依然として SQL Server と MySQL のみをサポートしていると述べています。

JPA アノテーションはまだ使用していませんが、XML 構成を使用した例を次に示します。

<id name="PRODUCT_ID">
  <generator class="guid" />
</id>

編集: 2 番目の質問に関しては、なぜ Hibernate が次のようなことができないのかを尋ねていると思います。

INSERT INTO PRODUCT (PRODUCT_ID, /* etc */)
SELECT SYSGUID(), /* etc */

その理由は、Hibernate がオブジェクトの ID を認識している必要があるためです。たとえば、次のシナリオを考えてみましょう。

  1. 新しい Product オブジェクトを作成して保存します。Oracle が ID を割り当てます。
  2. 製品を Hibernate セッションから切り離します。
  3. 後で再接続し、いくつかの変更を加えます。
  4. ここで、これらの変更を永続化したいと考えます。

ID がわからないと、Hibernate はこれを行うことができません。UPDATE ステートメントを発行するには ID が必要です。したがって、の実装は、 org.hibernate.id.GUIDGenerator 事前に ID を生成し、後で INSERT ステートメントでそれを再使用する必要があります。

これは Hibernate ができないのと同じ理由です 任意のバッチ処理 データベースで生成された ID (それをサポートするデータベースでの自動インクリメントを含む) を使用する場合。一度に多数のオブジェクトを挿入するときに優れたパフォーマンスを得るには、hilo ジェネレーターの 1 つ、または他の Hibernate 生成の ID メカニズムを使用することが唯一の方法です。

他のヒント

トピックスターターと同じタスクがあります。感謝をこめて @マット・ソルニット このような注釈を使用することを提案します。

@Id
@NotNull
@Column(name = "UUID")
@GenericGenerator(name = "db-uuid", strategy = "guid")
@GeneratedValue(generator = "db-uuid")
private String uuid;
public String getUuid() { return uuid; }
public void setUuid(String uuid) { this.uuid = uuid; }

strategy = "guid" そして String タイプはソリューションの重要な部分です。

新しいエンティティを永続化する前に、Hibernate は SQL クエリを発行します。

select rawtohex(sys_guid()) from dual

私のセットアップ:Oracle 11、Hibernate 4.3.4.Final、Spring 3.2.x。そしてフィールドは raw(16) を使用する場合よりも効率的なストレージとより小さいインデックスサイズのためにテーブルに char(32).

使おうとすると java.util.UUID IDフィールドタイプとして、新しいエンティティを永続化するとHibernateからエラーが発生します(設定しようとします) String に入力します java.util.UUID 分野)。

私も使っています javax.xml.bind.DatatypeConverter 非 Hibernate クエリ (Spring JDBC ヘルパー) の場合、convert を渡す場合 byte[]:

String query = "insert into TBL (UUID, COMPANY) values (:UUID, :COMPANY)";
MapSqlParameterSource parameters = new MapSqlParameterSource()
    .addValue("COMPANY", repo.getCompany())
    .addValue("UUID", DatatypeConverter.parseHexBinary(signal.getUuid()));
namedJdbcTemplate.update(query, parameters);

抽出用:

ResultSet rs;
sig.id = DatatypeConverter.printHexBinary(rs.getBytes("UUID"));

すべての Web コントローラーは次のようなコードを取得します。

025131763FB19522E050010A106D11E9

それなし {, -, } chars (UUID の通常の表現は {a-b-c-d-x-y} 覚えていれば)。この表現はすでに URL エンコードされており、クリーンかつ安全です。実装する必要はありません PropertyEditor または Convertor のために String タイプ:

@RequestMapping(value = {"/signal/edit/{id}.htm"}, method = RequestMethod.POST)
public String handleEditRequest(
        @PathVariable("id") String id,

失敗した使用試行と比較する jaa.util.UUID, 、ここで書く必要があります:

@Component
public static class UUIDPropertyEditor extends PropertyEditorSupport {
    @Override
    public void setAsText(final String str) {
        if (str == null || str.isEmpty()) {
            setValue(null);
            return;
        }
        setValue(UUID.fromString(str));
    }
}
private @Autowired UUIDPropertyEditor juuidPE;

@InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(UUIDPropertyEditor.class, juuidPE);
}

使用するには:

@PathVariable("id") UUID id,

ジェネレーターをネイティブに設定すればできると思います。Hibernate でそれを行う方法はよくわかりませんが、NHibernate では XML で次のようなことを行うことになります。

<id column="PRODUCT_ID">
  <generator class="native"/>
</id>
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top