Shiraaz.M
Shiraaz.M

Reputation: 3191

Hibernate/Oracle: How to make sequence execute within insert statement instead of two queries

I come from a jdbc background and I decided to teach myself to use hibernate. So I made a table with a sequence:

CREATE TABLE TST_PERSON(
ID NUMBER,
NAME VARCHAR(30),
SURNAME VARCHAR(30)
);

CREATE SEQUENCE TST_PERSON_SEQ MINVALUE 1 MAXVALUE 999999999999999999999999999 
INCREMENT BY 1 START WITH 1000 CACHE 20 NOORDER  NOCYCLE ;

and my java code for the mapping:

@Entity
@Table(name="TST_PERSON")
public class Person {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO,generator="pers_seq")
    @SequenceGenerator(name="pers_seq",sequenceName="TST_PERSON_SEQ")
    private Long id;

    @Column(name="NAME")
    private String name;

    @Column(name="SURNAME")
    private String surname;
    ... getters and setters ...
}

My hibernate configuration is:

    <?xml version='1.0' encoding='utf-8'?>
    <!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

    <hibernate-configuration>
        <session-factory>
            <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
            <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:sid</property>
            <property name="hibernate.connection.username">root</property>
            <property name="hibernate.connection.password">root</property>
            <property name="hibernate.connection.pool_size">10</property>
            <property name="show_sql">true</property>
            <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
            <property name="hibernate.current_session_context_class">thread</property>
            <mapping class="com.domain.Person"/>
        </session-factory>
    </hibernate-configuration>

But when I look at the SQL generated by Hibernate logs when calling session.save:

Hibernate: select TST_PERSON_SEQ.nextval from dual
Hibernate: insert into TST_PERSON (NAME, SURNAME, id) values (?, ?, ?)

I thought there might be some caching reasons but when I try to save through a loop I get the same output.

So the question is how do I get hibernate to include the sequence as part of the insert statement (which is what I intended to happen). In terms of versions I am using hibernate 4.1.8

Upvotes: 4

Views: 4904

Answers (1)

Sofian Djamaa
Sofian Djamaa

Reputation: 179

That's not possible actually. Let's take a simple example:

@SequenceGenerator(name="pers_seq",sequenceName="TST_PERSON_SEQ",allocationSize=10)

Allocation size is the equivalent of "INCREMENT BY 10". If you regroup ID retrieval query with the insert statement you'll have to detect when the 10th ID (TST_PERSON_SEQ.nextval) should be retrieved from the database at the same time than the insert.

Moreover, query batching on insertion occur for statements on the same table.

If you want to save some I/Os set a higher allocationSize and use JDBC batch mode (+ order_inserts property set to true eventually). This way you'll have a ID retrieval query each 10 insertions for an allocationSize set to 10.

Upvotes: 4

Related Questions