Domanda

Sto cercando un modo per ottenere in letargo per utilizzare la funzione di Oracle SYS_GUID() quando si inseriscono nuove righe. Attualmente le mie tabelle DB hanno <=> come default, quindi se hibernate SQL semplicemente generato che omited il valore dovrebbe funzionare.

Ho tutto lavorare, ma sta generando l'UUID / GUID nel codice utilizzando il sistema generatore-uuid:

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

Questo va bene, ma preferirei che i GUID sono stati generati dal database in modo che saranno sequenziale e potenzialmente avere prestazioni migliori. Inoltre vorrei solo sapere come configurare questo.

Sto usando le annotazioni per la configurazione, ma esempi di configurazione XML sono impressionanti pure.

Ecco una definizione di tabella di esempio (nel caso in cui è importante):

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:

sollution di Mat di utilizzare "guid" ha lavorato, qui è generato lo 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 (?, ?, ?, ?, ?, ?)

Sembra che utilizzando il valore predefinito colonne in un inserto non è possibile, quindi la scelta è tra un GUID applicazione generata e un giro di database.

È stato utile?

Soluzione

Si potrebbe essere in grado di utilizzare il generatore "guid". Vedere questo post dal forum Hibernate. Sembra che hanno aggiunto il supporto per Oracle utilizzando SYS_GUID() un po 'indietro, ma il documentazione dice ancora che supportano solo SQL Server e MySQL.

Non ho lavorato con annotazioni APP ancora, ma qui è un esempio usando configurazione XML:

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

Modifica Per quanto riguarda la seconda domanda, penso che ti stai chiedendo perché Hibernate non può fare qualcosa di simile:

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

Il motivo è che Hibernate deve sapere cosa l'ID dell'oggetto è. Ad esempio, si consideri il seguente scenario:

  1. Si crea un nuovo oggetto del prodotto e lo si salva. Oracle assegna l'ID.
  2. di scollegare il prodotto dalla sessione Hibernate.
  3. È successivamente re-attach e apportare alcune modifiche.
  4. È ora vuole persistere tali modifiche.

Senza conoscere l'ID, Hibernate non può fare questo. Ha bisogno l'ID, al fine di rilasciare l'istruzione UPDATE. Così l'attuazione di org.hibernate.id.GUIDGenerator deve generare l'ID in anticipo, e poi in seguito ri-utilizzarla nell'istruzione INSERT.

Questa è la stessa ragione per cui Hibernate non può fare qualsiasi dosaggio se si utilizza un database di ID-generated (tra cui auto-incremento su basi di dati che lo supportano). Utilizzando uno dei generatori Hilo, o qualche altro meccanismo ID Hibernate generato, è l'unico modo per ottenere buone prestazioni quando si inserisce un sacco di oggetti contemporaneamente.

Altri suggerimenti

Ho lo stesso compito che argomento di avviamento. Con grazie a suggerimento @ Matt Solnit che uso di tali annotazioni:

@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" e String tipo sono parti essenziali della soluzione.

Prima di persistere nuove entità Hibernate interrogazione SQL problema:

select rawtohex(sys_guid()) from dual

La mia configurazione: Oracle 11, Hibernate 4.3.4.Final, 3.2.x. Primavera E il campo è raw(16) nella tabella per l'archiviazione efficiente e meno dimensioni dell'indice allora se si utilizza char(32).

Quando provo ad usare java.util.UUID come tipo di campo ID ottengo l'errore da Hibernate sulla persistente nuova entità (si tenta di impostare il tipo di javax.xml.bind.DatatypeConverter byte[] campo).

Anche io uso { per le query non Hibernate (aiutanti Spring JDBC), per il passaggio di convertire in -:

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

per l'estrazione:

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

Tutti i controllori web Ottieni codici come:

025131763FB19522E050010A106D11E9

senza }, {a-b-c-d-x-y}, PropertyEditor caratteri (soliti rappresentazione di UUID è Convertor se lo ricordi). Questa rappresentazione già la codifica URL pulito e sicuro. Non è necessario implementare jaa.util.UUID o <=> per <=> tipo:

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

Confronto con tentativo fallito di usare <=>, dove ho bisogno di scrivere:

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

Per poter utilizzare:

@PathVariable("id") UUID id,

Credo che si può fare impostando il generatore per nativo. Io non sono davvero sicuro di come farlo in Hibernate, ma in NHibernate si farebbe qualcosa di simile in XML:

<id column="PRODUCT_ID">
  <generator class="native"/>
</id>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top