Você pode usar o gerador "guid". Veja este post do fórum do Hibernate. Parece que eles adicionaram suporte para Oracle usando
SYS_GUID()
um tempo atrás, mas a documentação ainda diz que eles suportam apenas SQL Server e MySQL. Ainda não trabalhei com anotações JPA, mas aqui está um exemplo usando a configuração XML:
<id name="PRODUCT_ID">
<generator class="guid" />
</id>
EDITAR: Em relação à sua segunda pergunta, acho que você está perguntando por que o Hibernate não pode fazer algo assim:
INSERT INTO PRODUCT (PRODUCT_ID, /* etc */)
SELECT SYSGUID(), /* etc */
A razão é que o Hibernate deve saber qual é o ID do objeto. Por exemplo, considere o seguinte cenário:
- Você cria um novo objeto Produto e o salva. A Oracle atribui o ID.
- Você desvincula o Produto da sessão do Hibernate.
- Você o anexa novamente e faz algumas alterações.
- Agora você deseja manter essas alterações.
Sem saber o ID, o Hibernate não pode fazer isso. Ele precisa do ID para emitir a instrução UPDATE. Portanto, a implementação de
org.hibernate.id.GUIDGenerator
tem que gerar o ID de antemão e depois reutilizá-lo na instrução INSERT. Esta é a mesma razão pela qual o Hibernate não pode fazer nenhum lote se você usar um ID gerado pelo banco de dados (incluindo incremento automático nos bancos de dados que o suportam). Usar um dos geradores hilo, ou algum outro mecanismo de ID gerado pelo Hibernate, é a única maneira de obter um bom desempenho ao inserir muitos objetos de uma só vez.