Question

Je cherche un moyen de mise en veille prolongée se d'utiliser la fonction Oracle lors SYS_GUID() insérer de nouvelles lignes. À l'heure actuelle mes tables de DB ont comme valeur par défaut <=> si hiberner simplement le SQL généré que la valeur qu'il entendue rectifier devrait fonctionner.

J'ai tout fonctionne, mais il génère actuellement le UUID / GUID dans le code en utilisant le générateur de système 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;
}

Ceci est bien, mais je préférerais que les GUIDs ont été générés par la base de données afin qu'ils soient séquentiels et potentiellement de meilleures performances. De plus, je voudrais savoir comment configurer cela.

J'utilise des annotations pour la configuration, mais des exemples de configuration XML sont super aussi.

Voici une définition de la table de l'échantillon (dans le cas où il importe):

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

Mise à jour:

Le sollution Mat d'utiliser "guid" a travaillé, voici le SQL généré:

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

Il semble que l'utilisation de la valeur par défaut des colonnes dans un insert n'est pas possible, donc le choix est entre une application générée guid et une base de données aller-retour.

Était-ce utile?

La solution

Vous pourriez être en mesure d'utiliser le générateur « guid ». Voir cette post du forum Mise en veille prolongée. On dirait qu'ils ont ajouté le support pour Oracle en utilisant un certain temps SYS_GUID(), mais le documentation dit encore qu'ils prennent en charge que SQL Server et MySQL.

Je n'ai pas travaillé avec annotations JPA encore, mais voici un exemple en utilisant la configuration XML:

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

EDIT: En ce qui concerne votre deuxième question, je pense que vous demandez pourquoi Hibernate ne peut pas faire quelque chose comme ceci:

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

La raison est que Hibernate doit savoir ce que l'ID de l'objet. Par exemple, considérons le scénario suivant:

  1. Vous créez un nouvel objet de produit et de l'enregistrer. Oracle attribue l'ID.
  2. Vous détachez le produit de la session Hibernate.
  3. Vous re-joindre plus tard et faire quelques changements.
  4. Vous voulez maintenant persister ces changements.

Sans connaître l'ID, Hibernate ne peut pas le faire. Il a besoin de l'ID afin d'émettre l'instruction UPDATE. Ainsi, la mise en œuvre de doit générer org.hibernate.id.GUIDGenerator l'ID au préalable, puis plus tard sur la réutilisation dans l'instruction INSERT.

Ceci est la même raison pour laquelle Hibernate ne peut pas faire tout batching si vous utilisez un ID généré base de données (y compris auto-augmentation des bases de données qui prennent en charge). L'utilisation d'un des générateurs hilo, ou un autre mécanisme d'ID généré Hibernate, est la seule façon d'obtenir de bonnes performances lors de l'insertion de nombreux objets à la fois.

Autres conseils

J'ai même tâche que démarreur sujet. Avec grâce à la suggestion Solnit @ Matt J'utilise ces annotations:

@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" et String type sont des éléments essentiels de la solution.

Avant la persistance de nouvelles entités à Hibernate requête SQL:

select rawtohex(sys_guid()) from dual

Ma configuration: Oracle 11, Hibernate 4.3.4.Final, Spring 3.2.x. Et le terrain est dans le tableau pour raw(16) stockage efficace et moins la taille de l'index alors si vous utilisez char(32).

Lorsque je tente d'utiliser comme type de java.util.UUID champ ID j'obtiens l'erreur de mise en veille prolongée sur une nouvelle entité persistante (il essaie de définir le type de champ javax.xml.bind.DatatypeConverter byte[]).

Aussi j'utilise pour les requêtes non {-Hibernate (Aides Spring JDBC), pour passer se convertir à -:

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

pour l'extraction:

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

Tous les contrôleurs web sont des codes comme:

025131763FB19522E050010A106D11E9

sans }, {a-b-c-d-x-y}, (représentation PropertyEditor caractères habituels de UUID est si vous vous souvenez Convertor). Cette représentation déjà URL encodage propre et sûr. Vous n'avez pas besoin de mettre en œuvre ou jaa.util.UUID pour <=> Type <=>:

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

Comparer avec tentative avortée d'utiliser <=>, où je dois écrire:

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

afin d'utiliser:

@PathVariable("id") UUID id,

Je pense que vous pouvez le faire en réglant le générateur natif. Je ne suis pas sûr de savoir comment faire en veille prolongée mais NHibernate vous feriez quelque chose comme ça dans le fichier XML:

<id column="PRODUCT_ID">
  <generator class="native"/>
</id>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top