web-dev-qa-db-fra.com

org.hibernate.dialect.OracleDialect ne prend pas en charge la génération de clé d'identité

J'essayais d'importer un exemple de projet dans Eclipse et je rencontrais l'erreur ci-dessous lors de l'exécution de l'application.

Caused by: org.hibernate.MappingException: org.hibernate.dialect.OracleDialect does not support identity key generation
    at org.hibernate.dialect.Dialect.getIdentityColumnString(Dialect.Java:743)
    at org.hibernate.dialect.Dialect.getIdentityColumnString(Dialect.Java:733)
    at org.hibernate.mapping.Table.sqlCreateString(Table.Java:426)
    at org.hibernate.cfg.Configuration.generateSchemaCreationScript(Configuration.Java:1028)
    at org.hibernate.tool.hbm2ddl.SchemaExport.<init>(SchemaExport.Java:125)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.Java:492)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.Java:1744)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.Java:1782)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBuilder.buildSessionFactory(LocalSessionFactoryBuilder.Java:247)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.Java:373)
    at org.springframework.orm.hibernate4.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.Java:358)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.Java:1541)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.Java:1479)
    ... 32 more

Selon le lien this SO, j'ai changé le

@GeneratedValue(strategy = GenerationType.IDENTITY)

à

@GeneratedValue(strategy = GenerationType.AUTO) ou @GeneratedValue(strategy = GenerationType.TABLE)

Mais ça n'a pas marché.

Voici le code:

User.Java:

@Entity
@Table(name = "users")
@ManagedBean
@ViewScoped
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;

    @Column(name = "username", nullable = false)
    private String username;

    @Column(name = "password", nullable = false)
    private String password;

    @Column(name = "role", nullable = false)
    private String role;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    }

À partir de l'applicationContext.xml:

<!-- Session Factory Declaration -->
<bean id="SessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="DataSource" />
    <property name="annotatedClasses">
        <list>
            <value>com.crud.model.User</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>

        </props>
    </property>
</bean>
12
NaaN

Vous pouvez utiliser tell Hibernate pour utiliser une séquence afin de générer vos identifiants.

@Id
@Column(name = "ID")
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "id_Sequence")
@SequenceGenerator(name = "id_Sequence", sequenceName = "ID_SEQ")
private int id;

Cette configuration demande en gros à Hibernate d'utiliser une séquence de base de données appelée ID_SEQ pour générer les identifiants pour cet objet. Vous pouvez spécifier d'autres séquences sur d'autres objets si vous voulez d'autres ID uniques ou vous pouvez utiliser la même séquence si vous voulez des ID uniques globaux sur l'ensemble de votre système.

Le seul inconvénient, c'est qu'il est impossible d'effectuer des insertions par lots (sans autre configuration) car Hibernate doit obtenir chaque fois la valeur de séquence suivante dans la base de données. Vous ne pouvez pas utiliser cette configuration si vous souhaitez utiliser une base de données MySQL , car ils ne supportent pas les séquences.

Si cela n'a aucun sens, faites-le-moi savoir et je l'expliquerai davantage.

20
JamesENL

Vous pouvez simplement utiliser @GeneratedValue(strategy = GenerationType.TABLE) s'il vous suffit de pouvoir incrémenter automatiquement la valeur d'attributs tels que certains ID qui est la clé primaire de votre table. Cela a fonctionné pour moi. J'espère que ça aide. 

1
iamharish15

ma réputation est trop basse ...

Eh bien, je suis très reconnaissant à JamesENL

J'ai substitué 

    @GeneratedValue(strategy = GenerationType.IDENTITY)

par 

    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "id_Sequence")
    @SequenceGenerator(name = "id_Sequence", sequenceName = "ID_SEQ")`

et ça marche bien

1
Jordi M.

Au lieu de IDENTITY, utilisez NATIVE et utilisez une séquence avec elle. Lien

0
Himanshu Tyagi