Frage

Ich bin auf der Suche nach einer Möglichkeit, verwenden SYS_GUID() Funktion des Orakels erhalten winter, wenn neue Zeilen einfügen. Zur Zeit haben meine DB-Tabellen als Standard SYS_GUID() also, wenn überwintern einfach generierten SQL, die den Wert omited sollte es funktionieren.

Ich habe alles funktioniert, aber es ist derzeit die UUID / GUID in Code zu erzeugen, den System-UUID-Generator mit:

@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;
}

Das ist in Ordnung, aber ich würde es vorziehen, dass die GUIDs von der Datenbank generiert wurden, so dass sie sequenziell sein wird und möglicherweise eine bessere Leistung haben. Plus Ich möchte nur wissen, wie diese zu konfigurieren.

Ich bin mit Anmerkungen zur Konfiguration, aber XML-Konfigurationsbeispiele sind auch genial.

Hier ist ein Beispiel Tabellendefinition (falls es wichtig ist):

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)
)

UPDATE:

Mat sollution der Verwendung von "guid" gearbeitet, hier ist die SQL generiert:

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

Es scheint, dass der Spalt Standardwert in einem Einsatz mit nicht möglich ist, so ist die Wahl zwischen einer Anwendung erzeugt guid und eine Datenbank Rundfahrt.

War es hilfreich?

Lösung

Sie könnten in der Lage sein, den „guid“ Generator. Siehe diesen Beitrag aus dem Hibernate-Forum. Es sieht aus wie sie Unterstützung für Oracle eine Weile zurück mit SYS_GUID(), aber die Dokumentation noch sagt, dass sie nur SQL Server und MySQL unterstützen.

Ich habe nicht mit JPA Anmerkungen arbeite noch, aber hier ist ein Beispiel unter Verwendung von XML-Konfiguration:

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

EDIT: In Bezug auf Ihre zweite Frage, ich glaube, Sie fragen, warum Hibernate kann so etwas nicht tun:

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

Der Grund dafür ist, dass Hibernate wissen müssen, was das Objekt ID ist. Betrachten wir zum Beispiel das folgende Szenario vor:

  1. Erstellen Sie ein neues Produkt Objekt und speichern. Oracle weist die ID.
  2. Sie lösen das Produkt aus der Hibernate-Session.
  3. Sie später wieder anbringen es und einige Änderungen vornehmen.
  4. Sie wollen nun diese Änderungen bestehen bleiben.

Ohne die ID zu kennen, kann Hibernate dies nicht tun. Es braucht die ID, um die UPDATE-Anweisung zu erteilen. So ist die Umsetzung von org.hibernate.id.GUIDGenerator hat die ID im Voraus zu erzeugen, und dann später wieder verwendet es in der INSERT-Anweisung.

Dies ist der gleiche Grund, warum Hibernate nicht tun jede Dosierung , wenn Sie eine Datenbank generierte ID verwenden (einschließlich Auto-Inkrement auf Datenbanken, die es unterstützen). Mithilfe der hilo Generatoren oder einen anderen Hibernate generierte ID-Mechanismus, ist der einzige Weg, eine gute Leistung zu erhalten, wenn viele Objekte auf einmal eingefügt wird.

Andere Tipps

Ich habe gleiche Aufgabe dieses Thema Starter. Mit Dank an @ Matt Solnit Vorschlag verwende ich solche Anmerkungen:

@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" und String Typ sind wesentliche Bestandteile der Lösung aus.

Vor dem neuen Einheiten Hibernate Problem SQL-Abfrage persistierenden:

select rawtohex(sys_guid()) from dual

Mein Setup: Oracle 11, Hibernate 4.3.4.Final, Frühling 3.2.x Und Feld ist raw(16) in der Tabelle für eine effiziente Speicherung und geringere Indexgröße dann, wenn Sie char(32) verwenden.

Wenn ich versuche zu verwenden java.util.UUID als ID-Feld Typ-I-Fehler aus dem Ruhezustand erhalte auf neue Einheit persistierende (es versucht String Typen einzustellen Feld zu java.util.UUID).

Auch ich verwende javax.xml.bind.DatatypeConverter für Nicht-Hibernate-Abfragen (Frühjahr JDBC Helfer), zu byte[] konvertieren vorbei:

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);

zum Extrahieren:

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

Alle Web-Controller erhalten Codes wie:

025131763FB19522E050010A106D11E9

ohne {, -, } Zeichen (übliche Darstellung von UUID ist {a-b-c-d-x-y} wenn Sie sich erinnern). Diese Darstellung bereits URL-Codierung sauber und sicher. Sie brauchen nicht PropertyEditor oder Convertor für String Typ zu implementieren:

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

Vergleichen mit gescheiterten Versuch jaa.util.UUID zu verwenden, wo ich schreiben müssen:

@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);
}

zu verwenden, um:

@PathVariable("id") UUID id,

Ich glaube, Sie können es durch den Generator zu nativen Einstellung. Ich bin nicht wirklich sicher, wie es in dem Ruhezustand zu tun, aber in NHibernate würden Sie so etwas wie dies in der XML tun:

<id column="PRODUCT_ID">
  <generator class="native"/>
</id>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top