24

I was trying to import a sample project in to eclipse and was facing the below given error up on running the 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

As per this SO link, I have changed the

@GeneratedValue(strategy = GenerationType.IDENTITY)

to

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

But didn't work.

Here is the 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;
    }

    }

From the 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>
Community
  • 1
  • 1
Nidheesh
  • 4,390
  • 29
  • 87
  • 150

11 Answers11

31

You can use tell Hibernate to use a sequence to generate your ID's

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

This config basically tells Hibernate to use a database sequence called ID_SEQ to generate the ID's for this object. You can specify other sequences on other objects if you want other unique ID's or you can use the same sequence if you want globally unique ID's across your entire system.

The only downside to this is that can't perform batch inserts (without some further config) because Hibernate needs to get the next sequence value from the database every time, and you can't use this config if you want to use a MySQL database, because they don't support sequences.

If any of that doesn't make sense let me know and I'll explain it further.

JamesENL
  • 6,400
  • 6
  • 39
  • 64
  • Not sure why I am getting the same error again, even though we are not using `IDENTITY`. I'm using `Oracle` DB – Nidheesh Jun 03 '14 at 07:31
  • 4
    Remove the hibernate.dialect line of config. Hibernate will autodetect the dialect to use. I'm pretty sure that the OracleDialect is for much older oracle databases. – JamesENL Jun 03 '14 at 07:32
  • Throws, `Connection cannot be null when 'hibernate.dialect' not set` – Nidheesh Jun 03 '14 at 07:35
  • Can you post your `dataSource` declaration? That error message means that Hibernate can't connect to your database – JamesENL Jun 03 '14 at 07:35
  • Join us here - http://chat.stackoverflow.com/rooms/44929/java-spring-hibernate-php-jquery-javascript-beginners – JamesENL Jun 03 '14 at 07:36
  • +1 for your useful suggestion. I have started this example step by step from scratch with a new db and the same way `GenerationType.SEQUENCE` as you mentioned. Now I am able to get the app connected to db. Much thanks. – Nidheesh Jun 05 '14 at 09:46
  • Thank you .My issue is fixed with this solution. – java.nazif Feb 01 '17 at 07:53
  • Great Suggestion Indeed. However I would like to add that the sequence name should be the same as that of the table sequence name. Plus you need to know that the default sequence jump is 50. So you need to set it to the same increment value as you are using in your table sequence. you can use the option : allocationSize = 1 – Som Jan 01 '19 at 11:26
19

I also had the same problem I am using OracleDB, I tried Identity, GenerateSequence and nothing gave me the solution. Until I had to change the dialect in my application properties. For some reason the dialect was not generating the correct sequence, which is why I decided to use a different dialect for my Oracle12c case.

Before:

spring.jpa.database-platform = org.hibernate.dialect.Oracle10gDialect

Then:

spring.jpa.database-platform = org.hibernate.dialect.Oracle12cDialect

You could verify that you have value in the dialect of your connection maybe and changing it to a different version will be resolved like me.

Chema
  • 2,748
  • 2
  • 13
  • 24
  • Please add code lines properly, follow this link: https://meta.stackexchange.com/questions/22186/how-do-i-format-my-code-blocks – Chema May 26 '20 at 20:54
  • And please avoid salutations and greetings: https://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts – Chema May 26 '20 at 20:56
3

my reputation is too low...

Well, I'm very grateful to JamesENL

I substituted

    @GeneratedValue(strategy = GenerationType.IDENTITY)

by

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

and that works fine

Jordi M.
  • 69
  • 3
  • @All, If you do not specify `@SequenceGenerator`, sequence name defaults(at least Hibernate) to a value which is specified for `generator` i.e., `id_sequence`. – lupchiazoem Jul 29 '19 at 07:56
  • @All Addendum to above comment - Also, if there's no generator defined like `@org.hibernate.annotations.GenericGenerator`. – lupchiazoem Jul 29 '19 at 08:53
2

You can just use @GeneratedValue(strategy = GenerationType.TABLE) if you just need to be able to auto increment the value for attributes such as some ID which is primary key of your table. It worked for me. Hope it helps.

iamharish15
  • 1,760
  • 1
  • 17
  • 20
2

The reason for exception is:

Hibernate expects from underlying database to provide an auto increment feature for a given property, in your case it's id. IOW, Oracle(your case) should support auto increment feature for a field. Oracle started to provide auto increment feature with 12c version and, as your version was less, you got that exception .

lupchiazoem
  • 8,026
  • 6
  • 36
  • 42
1

In my sample project, I have only used @Id. in hibernate.cfg.xml, I have used Oracle9iDialect previously. I have changed it to Oracle12cDialect and it worked.

<property name="dialect">org.hibernate.dialect.Oracle12cDialect</property>
Abd Abughazaleh
  • 4,615
  • 3
  • 44
  • 53
1

Please Change The Oracle Dialect as Older Dialects Doesnt Support key generation e.g. try org.hibernate.dialect.Oracle12cDialect

  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 19 '23 at 10:32
0

Instead of IDENTITY use NATIVE and use a sequence with it. Link

Himanshu Tyagi
  • 5,201
  • 1
  • 23
  • 43
0

You can change .identity by .sequence and it will work:

GeneratedValue(strategy=GenerationType.SEQUENCE)
סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
0

if you use oracle 12c I can add to column id GENERATED ALWAYS AS IDENTITY for example

"ID" NUMBER (20,0) GENERATED ALWAYS AS IDENTITY

in application.properties modify the value

spring.jpa.database-platform = org.hibernate.dialect.Oracle12cDialect

and in the entity

 @Id
 @GeneratedValue (strategy = GenerationType.IDENTITY)
 private Long id;
Yu Hao
  • 119,891
  • 44
  • 235
  • 294
eyvmen
  • 11
0

I added @GeneratedValue(strategy = GenerationType.TABLE) instead of @GeneratedValue(strategy = GenerationType.IDENTITY)

Also remove the GENERATED ALWAYS as IDENTITY(START with 1 INCREMENT by 1) if you are added, from oracle table.

It is working for me.

lkatiforis
  • 5,703
  • 2
  • 16
  • 35
Ritunjay kumar
  • 261
  • 3
  • 6